2018-09-11 00:44:54 +08:00
|
|
|
#include "Instruction.h"
|
|
|
|
|
|
|
|
|
2018-10-10 18:08:53 +08:00
|
|
|
Instruction::Instruction(sc_uint<32> instr) {
|
2018-09-11 00:44:54 +08:00
|
|
|
m_instr = instr;
|
|
|
|
}
|
|
|
|
|
|
|
|
opCodes Instruction::decode() {
|
|
|
|
switch (opcode()) {
|
|
|
|
case LUI:
|
|
|
|
return OP_LUI;
|
|
|
|
case AUIPC:
|
|
|
|
return OP_AUIPC;
|
|
|
|
case JAL:
|
|
|
|
return OP_JAL;
|
|
|
|
case JALR:
|
|
|
|
return OP_JALR;
|
|
|
|
case BEQ:
|
2018-10-10 18:08:53 +08:00
|
|
|
switch(get_funct3()) {
|
2018-09-11 00:44:54 +08:00
|
|
|
case BEQ_F:
|
|
|
|
return OP_BEQ;
|
|
|
|
case BNE_F:
|
|
|
|
return OP_BNE;
|
|
|
|
case BLT_F:
|
|
|
|
return OP_BLT;
|
|
|
|
case BGE_F:
|
|
|
|
return OP_BGE;
|
|
|
|
case BLTU_F:
|
|
|
|
return OP_BLTU;
|
|
|
|
case BGEU_F:
|
|
|
|
return OP_BGEU;
|
|
|
|
}
|
|
|
|
return OP_ERROR;
|
|
|
|
case LB:
|
2018-10-10 18:08:53 +08:00
|
|
|
switch(get_funct3()) {
|
2018-09-11 00:44:54 +08:00
|
|
|
case LB_F:
|
|
|
|
return OP_LB;
|
|
|
|
case LH_F:
|
|
|
|
return OP_LH;
|
|
|
|
case LW_F:
|
|
|
|
return OP_LW;
|
|
|
|
case LBU_F:
|
|
|
|
return OP_LBU;
|
|
|
|
case LHU_F:
|
|
|
|
return OP_LHU;
|
|
|
|
}
|
|
|
|
return OP_ERROR;
|
|
|
|
case SB:
|
2018-10-10 18:08:53 +08:00
|
|
|
switch(get_funct3()) {
|
2018-09-11 00:44:54 +08:00
|
|
|
case SB_F:
|
|
|
|
return OP_SB;
|
|
|
|
case SH_F:
|
|
|
|
return OP_SH;
|
|
|
|
case SW_F:
|
|
|
|
return OP_SW;
|
|
|
|
}
|
|
|
|
return OP_ERROR;
|
|
|
|
case ADDI:
|
2018-10-10 18:08:53 +08:00
|
|
|
switch(get_funct3()) {
|
2018-09-11 00:44:54 +08:00
|
|
|
case ADDI_F:
|
|
|
|
return OP_ADDI;
|
|
|
|
case SLTI_F:
|
|
|
|
return OP_SLTI;
|
|
|
|
case SLTIU_F:
|
|
|
|
return OP_SLTIU;
|
|
|
|
case XORI_F:
|
|
|
|
return OP_XORI;
|
|
|
|
case ORI_F:
|
|
|
|
return OP_ORI;
|
|
|
|
case ANDI_F:
|
|
|
|
return OP_ANDI;
|
|
|
|
case SLLI_F:
|
|
|
|
return OP_SLLI;
|
|
|
|
case SRLI_F:
|
2018-10-10 18:08:53 +08:00
|
|
|
switch(get_funct7()) {
|
2018-09-11 00:44:54 +08:00
|
|
|
case SRLI_F7:
|
|
|
|
return OP_SRLI;
|
|
|
|
case SRAI_F7:
|
|
|
|
return OP_SRAI;
|
|
|
|
}
|
|
|
|
return OP_ERROR;
|
|
|
|
}
|
|
|
|
return OP_ERROR;
|
|
|
|
case ADD: {
|
2018-10-10 18:08:53 +08:00
|
|
|
switch(get_funct3()) {
|
2018-09-11 00:44:54 +08:00
|
|
|
case ADD_F:
|
2018-10-10 18:08:53 +08:00
|
|
|
switch (get_funct7()) {
|
2018-09-11 00:44:54 +08:00
|
|
|
case ADD_F7:
|
|
|
|
return OP_ADD;
|
|
|
|
case SUB_F7:
|
|
|
|
return OP_SUB;
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
case SLL_F:
|
|
|
|
return OP_SLL;
|
|
|
|
case SLT_F:
|
|
|
|
return OP_SLT;
|
|
|
|
case SLTU_F:
|
|
|
|
return OP_SLTU;
|
|
|
|
case XOR_F:
|
|
|
|
return OP_XOR;
|
|
|
|
case SRL_F:
|
2018-10-10 18:08:53 +08:00
|
|
|
switch(get_funct7()) {
|
2018-09-11 00:44:54 +08:00
|
|
|
case SRL_F7:
|
|
|
|
return OP_SRL;
|
|
|
|
case SRA_F7:
|
|
|
|
return OP_SRA;
|
|
|
|
}
|
|
|
|
case OR_F:
|
|
|
|
return OP_OR;
|
|
|
|
case AND_F:
|
|
|
|
return OP_AND;
|
|
|
|
}
|
|
|
|
} /* ADD */
|
2018-10-15 19:51:41 +08:00
|
|
|
case FENCE:
|
|
|
|
return OP_FENCE;
|
|
|
|
case ECALL: {
|
|
|
|
switch (get_funct3()) {
|
|
|
|
case ECALL_F3:
|
|
|
|
switch(get_csr()) {
|
|
|
|
case ECALL_F:
|
|
|
|
return OP_ECALL;
|
|
|
|
case EBREAK_F:
|
|
|
|
return OP_EBREAK;
|
|
|
|
case URET_F:
|
|
|
|
return OP_URET;
|
|
|
|
case SRET_F:
|
|
|
|
return OP_SRET;
|
|
|
|
case MRET_F:
|
|
|
|
return OP_MRET;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CSRRW:
|
|
|
|
return OP_CSRRW;
|
|
|
|
break;
|
|
|
|
case CSRRS:
|
|
|
|
return OP_CSRRS;
|
|
|
|
break;
|
|
|
|
case CSRRC:
|
|
|
|
return OP_CSRRC;
|
|
|
|
break;
|
|
|
|
case CSRRWI:
|
|
|
|
return OP_CSRRWI;
|
|
|
|
break;
|
|
|
|
case CSRRSI:
|
|
|
|
return OP_CSRRSI;
|
|
|
|
break;
|
|
|
|
case CSRRCI:
|
|
|
|
return OP_CSRRCI;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-09-11 00:44:54 +08:00
|
|
|
default:
|
|
|
|
return OP_ERROR;
|
|
|
|
}
|
|
|
|
}
|
2018-10-15 19:51:41 +08:00
|
|
|
|
|
|
|
|
|
|
|
extension_t Instruction::check_extension() {
|
|
|
|
if (m_instr.range(1,0) == 0b11) {
|
|
|
|
return BASE_EXTENSION;
|
|
|
|
} else if (m_instr.range(1,0) == 0b00) {
|
|
|
|
return C_EXTENSION;
|
|
|
|
} else if (m_instr.range(1,0) == 0b01) {
|
|
|
|
return C_EXTENSION;
|
|
|
|
} else if (m_instr.range(1,0) == 0b10) {
|
|
|
|
return C_EXTENSION;
|
|
|
|
} else if (m_instr.range(6,0) == 0b0110011) {
|
|
|
|
return M_EXTENSION;
|
|
|
|
} else if (m_instr.range(6,0) == 0b0101111) {
|
|
|
|
return A_EXTENSION;
|
|
|
|
} else {
|
|
|
|
return UNKNOWN_EXTENSION;
|
|
|
|
}
|
|
|
|
}
|