add op field to the Ins struct
This commit is contained in:
507
riscv64.cc
507
riscv64.cc
@@ -82,8 +82,73 @@ static constexpr std::array<const char *, 32> REGS = {
|
|||||||
"a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5",
|
"a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5",
|
||||||
"s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"};
|
"s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"};
|
||||||
|
|
||||||
|
enum class Op {
|
||||||
|
ADD,
|
||||||
|
ADDI,
|
||||||
|
ADDIW,
|
||||||
|
ADDW,
|
||||||
|
AND,
|
||||||
|
ANDI,
|
||||||
|
AUIPC,
|
||||||
|
BEQ,
|
||||||
|
BGE,
|
||||||
|
BGEU,
|
||||||
|
BLT,
|
||||||
|
BLTU,
|
||||||
|
BNE,
|
||||||
|
DIV,
|
||||||
|
DIVU,
|
||||||
|
DIVUW,
|
||||||
|
DIVW,
|
||||||
|
ECALL,
|
||||||
|
JAL,
|
||||||
|
JALR,
|
||||||
|
LB,
|
||||||
|
LBU,
|
||||||
|
LD,
|
||||||
|
LH,
|
||||||
|
LHU,
|
||||||
|
LUI,
|
||||||
|
LW,
|
||||||
|
LWU,
|
||||||
|
MUL,
|
||||||
|
MULH,
|
||||||
|
MULHU,
|
||||||
|
MULW,
|
||||||
|
OR,
|
||||||
|
ORI,
|
||||||
|
REM,
|
||||||
|
REMU,
|
||||||
|
REMUW,
|
||||||
|
REMW,
|
||||||
|
SB,
|
||||||
|
SD,
|
||||||
|
SH,
|
||||||
|
SLL,
|
||||||
|
SLLI,
|
||||||
|
SLLIW,
|
||||||
|
SLLW,
|
||||||
|
SLT,
|
||||||
|
SLTI,
|
||||||
|
SLTIU,
|
||||||
|
SLTU,
|
||||||
|
SRA,
|
||||||
|
SRAI,
|
||||||
|
SRAIW,
|
||||||
|
SRAW,
|
||||||
|
SRL,
|
||||||
|
SRLI,
|
||||||
|
SRLIW,
|
||||||
|
SRLW,
|
||||||
|
SUB,
|
||||||
|
SUBW,
|
||||||
|
SW,
|
||||||
|
XOR,
|
||||||
|
XORI
|
||||||
|
};
|
||||||
|
|
||||||
struct Ins {
|
struct Ins {
|
||||||
u8 opcode;
|
Op op;
|
||||||
u8 rd;
|
u8 rd;
|
||||||
u8 funct3;
|
u8 funct3;
|
||||||
u8 rs1;
|
u8 rs1;
|
||||||
@@ -131,8 +196,9 @@ public:
|
|||||||
|
|
||||||
void disassemble_one_fetch() {
|
void disassemble_one_fetch() {
|
||||||
Ins ins = fetch_ins();
|
Ins ins = fetch_ins();
|
||||||
std::println("{} {} {} {} {} {} {} {} {}", ins.opcode, ins.rd, ins.funct3,
|
std::println("{} {} {} {} {} {} {} {} {}", static_cast<i32>(ins.op), ins.rd,
|
||||||
ins.rs1, ins.rs2, ins.funct7, ins.shamt, ins.funct6, ins.imm);
|
ins.funct3, ins.rs1, ins.rs2, ins.funct7, ins.shamt,
|
||||||
|
ins.funct6, ins.imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassemble_one() {
|
void disassemble_one() {
|
||||||
@@ -398,19 +464,19 @@ public:
|
|||||||
}
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 0b0011011: {
|
case 0b0011011: {
|
||||||
u8 funct3 = (ins >> 12) & 0b111;
|
|
||||||
if (funct3 == 0b000) {
|
|
||||||
PARSE_I_INS(ins);
|
PARSE_I_INS(ins);
|
||||||
|
if (funct3 == 0b000) {
|
||||||
std::println("addiw {}, {}, {}", REGS[rd], REGS[rs1], imm);
|
std::println("addiw {}, {}, {}", REGS[rd], REGS[rs1], imm);
|
||||||
} else if (funct3 == 0b001) {
|
} else if (funct3 == 0b001) {
|
||||||
PARSE_R_INS(ins); // TODO: probably wrong
|
u32 shamt = (ins >> 20) & 0b11111;
|
||||||
std::println("slliw {}, {}, {}", REGS[rd], REGS[rs1], rs2);
|
std::println("slliw {}, {}, {}", REGS[rd], REGS[rs1], shamt);
|
||||||
} else if (funct3 == 0b101) {
|
} else if (funct3 == 0b101) {
|
||||||
PARSE_R_INS(ins);
|
u32 shamt = (ins >> 20) & 0b11111;
|
||||||
|
u8 funct7 = (ins >> 25) & 0b1111111;
|
||||||
if (funct7 == 0b0000000) {
|
if (funct7 == 0b0000000) {
|
||||||
std::println("srliw {}, {}, {}", REGS[rd], REGS[rs1], rs2);
|
std::println("srliw {}, {}, {}", REGS[rd], REGS[rs1], shamt);
|
||||||
} else if (funct7 == 0b0100000) {
|
} else if (funct7 == 0b0100000) {
|
||||||
std::println("sraiw {}, {}, {}", REGS[rd], REGS[rs1], rs2);
|
std::println("sraiw {}, {}, {}", REGS[rd], REGS[rs1], shamt);
|
||||||
} else {
|
} else {
|
||||||
std::println(stderr,
|
std::println(stderr,
|
||||||
"R-type 4: funct3=101: unrecognized funct7: {:b}",
|
"R-type 4: funct3=101: unrecognized funct7: {:b}",
|
||||||
@@ -857,15 +923,16 @@ public:
|
|||||||
PARSE_I_INS(ins);
|
PARSE_I_INS(ins);
|
||||||
if (funct3 == 0b000) { // addiw
|
if (funct3 == 0b000) { // addiw
|
||||||
m_regs[rd] = (i32)m_regs[rs1] + (i32)imm;
|
m_regs[rd] = (i32)m_regs[rs1] + (i32)imm;
|
||||||
} else if (funct3 == 0b001) {
|
} else if (funct3 == 0b001) { // slliw
|
||||||
u32 shamt = (ins >> 20) & 0b11111;
|
u32 shamt = (ins >> 20) & 0b11111;
|
||||||
m_regs[rd] = (i32)m_regs[rs1] << shamt;
|
m_regs[rd] = (i32)m_regs[rs1] << shamt;
|
||||||
} else if (funct3 == 0b101) {
|
} else if (funct3 == 0b101) {
|
||||||
PARSE_R_INS(ins);
|
u32 shamt = (ins >> 20) & 0b11111;
|
||||||
|
u8 funct7 = (ins >> 25) & 0b1111111;
|
||||||
if (funct7 == 0b0000000) { // srliw
|
if (funct7 == 0b0000000) { // srliw
|
||||||
m_regs[rd] = (i32)((u32)m_regs[rs1] >> rs2);
|
m_regs[rd] = (i32)((u32)m_regs[rs1] >> shamt);
|
||||||
} else if (funct7 == 0b0100000) { // sraiw
|
} else if (funct7 == 0b0100000) { // sraiw
|
||||||
m_regs[rd] = (i32)m_regs[rs1] >> rs2;
|
m_regs[rd] = (i32)m_regs[rs1] >> shamt;
|
||||||
} else {
|
} else {
|
||||||
std::println(stderr,
|
std::println(stderr,
|
||||||
"R-type 4: funct3=101: unrecognized funct7: {:b}",
|
"R-type 4: funct3=101: unrecognized funct7: {:b}",
|
||||||
@@ -947,89 +1014,331 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ins fetch_ins() {
|
Ins fetch_ins() {
|
||||||
u32 ins;
|
u32 raw;
|
||||||
std::memcpy(&ins, m_memory.data() + m_pc, sizeof(ins));
|
std::memcpy(&raw, m_memory.data() + m_pc, sizeof(raw));
|
||||||
|
|
||||||
u8 opcode = ins & 0b1111111;
|
u8 opcode = raw & 0b1111111;
|
||||||
|
|
||||||
|
Ins i;
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case 0b1100011: {
|
case 0b1100011: {
|
||||||
u8 funct3 = (ins >> 12) & 0b111;
|
i.funct3 = (raw >> 12) & 0b111;
|
||||||
u8 rs1 = (ins >> 15) & 0b11111;
|
i.rs1 = (raw >> 15) & 0b11111;
|
||||||
u8 rs2 = (ins >> 20) & 0b11111;
|
i.rs2 = (raw >> 20) & 0b11111;
|
||||||
i32 imm_12 = (ins >> 31) & 0b1;
|
i32 imm_12 = (raw >> 31) & 0b1;
|
||||||
i32 imm_10_5 = (ins >> 25) & 0b111111;
|
i32 imm_10_5 = (raw >> 25) & 0b111111;
|
||||||
i32 imm_4_1 = (ins >> 8) & 0b1111;
|
i32 imm_4_1 = (raw >> 8) & 0b1111;
|
||||||
i32 imm_11 = (ins >> 7) & 0b1;
|
i32 imm_11 = (raw >> 7) & 0b1;
|
||||||
i32 imm =
|
i.imm =
|
||||||
(imm_12 << 12) | (imm_11 << 11) | (imm_10_5 << 5) | (imm_4_1 << 1);
|
(imm_12 << 12) | (imm_11 << 11) | (imm_10_5 << 5) | (imm_4_1 << 1);
|
||||||
imm = (imm << 19) >> 19;
|
i.imm = (i.imm << 19) >> 19;
|
||||||
|
|
||||||
return Ins{.opcode = opcode,
|
if (i.funct3 == 0b000) {
|
||||||
.funct3 = funct3,
|
i.op = Op::BEQ;
|
||||||
.rs1 = rs1,
|
} else if (i.funct3 == 0b001) {
|
||||||
.rs2 = rs2,
|
i.op = Op::BNE;
|
||||||
.imm = imm};
|
} else if (i.funct3 == 0b100) {
|
||||||
|
i.op = Op::BLT;
|
||||||
|
} else if (i.funct3 == 0b101) {
|
||||||
|
i.op = Op::BGE;
|
||||||
|
} else if (i.funct3 == 0b110) {
|
||||||
|
i.op = Op::BLTU;
|
||||||
|
} else if (i.funct3 == 0b111) {
|
||||||
|
i.op = Op::BGEU;
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "B-type: unrecognized funct3: {:03b}", i.funct3);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 0b0010011:
|
case 0b0010011: {
|
||||||
case 0b0000011:
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
case 0b1100111:
|
i.funct3 = (raw >> 12) & 0b111;
|
||||||
case 0b1110011: {
|
i.rs1 = (raw >> 15) & 0b11111;
|
||||||
u8 rd = (ins >> 7) & 0b11111;
|
i.imm = ((i32)raw) >> 20;
|
||||||
u8 funct3 = (ins >> 12) & 0b111;
|
i.shamt = (raw >> 20) & 0b111111;
|
||||||
u8 rs1 = (ins >> 15) & 0b11111;
|
i.funct6 = (raw >> 26) & 0b111111;
|
||||||
i32 imm = ((i32)ins) >> 20;
|
|
||||||
|
|
||||||
return Ins{
|
if (i.funct3 == 0b000) {
|
||||||
.opcode = opcode, .rd = rd, .funct3 = funct3, .rs1 = rs1, .imm = imm};
|
i.op = Op::ADDI;
|
||||||
|
} else if (i.funct3 == 0b001) {
|
||||||
|
if (i.funct6 == 0b000000) {
|
||||||
|
i.op = Op::SLLI;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"I-type 1: funct3=001: unrecognized funct6: {:b}",
|
||||||
|
i.funct6);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b010) {
|
||||||
|
i.op = Op::SLTI;
|
||||||
|
} else if (i.funct3 == 0b011) {
|
||||||
|
i.op = Op::SLTIU;
|
||||||
|
} else if (i.funct3 == 0b100) {
|
||||||
|
i.op = Op::XORI;
|
||||||
|
} else if (i.funct3 == 0b101) {
|
||||||
|
i.shamt = (raw >> 20) & 0b111111;
|
||||||
|
i.funct6 = (raw >> 26) & 0b111111;
|
||||||
|
|
||||||
|
if (i.funct6 == 0b000000) {
|
||||||
|
i.op = Op::SRLI;
|
||||||
|
} else if (i.funct6 == 0b010000) {
|
||||||
|
i.op = Op::SRAI;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"I-type 1: funct3=101: unrecognized funct6: {:b}",
|
||||||
|
i.funct6);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b110) {
|
||||||
|
i.op = Op::ORI;
|
||||||
|
} else if (i.funct3 == 0b111) {
|
||||||
|
i.op = Op::ANDI;
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "I-type 1: unrecognized funct3: {:03b}", i.funct3);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case 0b0000011: {
|
||||||
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
|
i.funct3 = (raw >> 12) & 0b111;
|
||||||
|
i.rs1 = (raw >> 15) & 0b11111;
|
||||||
|
i.imm = ((i32)raw) >> 20;
|
||||||
|
|
||||||
|
if (i.funct3 == 0b000) {
|
||||||
|
i.op = Op::LB;
|
||||||
|
} else if (i.funct3 == 0b001) {
|
||||||
|
i.op = Op::LH;
|
||||||
|
} else if (i.funct3 == 0b010) {
|
||||||
|
i.op = Op::LW;
|
||||||
|
} else if (i.funct3 == 0b011) {
|
||||||
|
i.op = Op::LD;
|
||||||
|
} else if (i.funct3 == 0b100) {
|
||||||
|
i.op = Op::LBU;
|
||||||
|
} else if (i.funct3 == 0b101) {
|
||||||
|
i.op = Op::LHU;
|
||||||
|
} else if (i.funct3 == 0b110) {
|
||||||
|
i.op = Op::LWU;
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "I-type 2: unrecognized funct3: {:03b}", i.funct3);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case 0b1100111: {
|
||||||
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
|
i.funct3 = (raw >> 12) & 0b111;
|
||||||
|
i.rs1 = (raw >> 15) & 0b11111;
|
||||||
|
i.imm = ((i32)raw) >> 20;
|
||||||
|
i.op = Op::JALR;
|
||||||
|
}; break;
|
||||||
|
case 0b1110011: {
|
||||||
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
|
i.funct3 = (raw >> 12) & 0b111;
|
||||||
|
i.rs1 = (raw >> 15) & 0b11111;
|
||||||
|
i.imm = ((i32)raw) >> 20;
|
||||||
|
|
||||||
|
if (i.funct3 == 0b000) {
|
||||||
|
if (i.imm == 0) {
|
||||||
|
i.op = Op::ECALL;
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "I-type 4: funct3=000 unrecognized imm: {:b}",
|
||||||
|
i.imm);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "I-type 4: unrecognized funct3: {:03b}", i.funct3);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 0b1101111: {
|
case 0b1101111: {
|
||||||
u8 rd = (ins >> 7) & 0b11111;
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
i32 imm_20 = (ins >> 31) & 0b1;
|
i32 imm_20 = (raw >> 31) & 0b1;
|
||||||
i32 imm_10_1 = (ins >> 21) & 0b1111111111;
|
i32 imm_10_1 = (raw >> 21) & 0b1111111111;
|
||||||
i32 imm_11 = (ins >> 20) & 0b1;
|
i32 imm_11 = (raw >> 20) & 0b1;
|
||||||
i32 imm_19_12 = (ins >> 12) & 0b11111111;
|
i32 imm_19_12 = (raw >> 12) & 0b11111111;
|
||||||
i32 imm =
|
i.imm =
|
||||||
(imm_20 << 20) | (imm_19_12 << 12) | (imm_11 << 11) | (imm_10_1 << 1);
|
(imm_20 << 20) | (imm_19_12 << 12) | (imm_11 << 11) | (imm_10_1 << 1);
|
||||||
imm = (imm << 11) >> 11;
|
i.imm = (i.imm << 11) >> 11;
|
||||||
|
i.op = Op::JAL;
|
||||||
|
}; break;
|
||||||
|
case 0b0110011: {
|
||||||
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
|
i.funct3 = (raw >> 12) & 0b111;
|
||||||
|
i.rs1 = (raw >> 15) & 0b11111;
|
||||||
|
i.rs2 = (raw >> 20) & 0b11111;
|
||||||
|
i.funct7 = (u8)((raw >> 25) & 0b1111111);
|
||||||
|
|
||||||
return Ins{.opcode = opcode, .rd = rd, .imm = imm};
|
if (i.funct3 == 0b000) {
|
||||||
|
if (i.funct7 == 0b0000000) {
|
||||||
|
i.op = Op::ADD;
|
||||||
|
} else if (i.funct7 == 0b0100000) {
|
||||||
|
i.op = Op::SUB;
|
||||||
|
} else if (i.funct7 == 0b0000001) {
|
||||||
|
i.op = Op::MUL;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 1: funct3=0b000: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b001) {
|
||||||
|
if (i.funct7 == 0b0000000) {
|
||||||
|
i.op = Op::SLL;
|
||||||
|
} else if (i.funct7 == 0b0000001) {
|
||||||
|
i.op = Op::MULH;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 1: funct3=0b001: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b010) {
|
||||||
|
if (i.funct7 == 0b0000000) {
|
||||||
|
i.op = Op::SLT;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 1: funct3=0b010: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b011) {
|
||||||
|
if (i.funct7 == 0b0000000) {
|
||||||
|
i.op = Op::SLTU;
|
||||||
|
} else if (i.funct7 == 0b0000001) {
|
||||||
|
i.op = Op::MULHU;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 1: funct3=0b011: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b100) {
|
||||||
|
if (i.funct7 == 0b0000000) {
|
||||||
|
i.op = Op::XOR;
|
||||||
|
} else if (i.funct7 == 0b0000001) {
|
||||||
|
i.op = Op::DIV;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 1: funct3=0b100: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b101) {
|
||||||
|
if (i.funct7 == 0b0000000) {
|
||||||
|
i.op = Op::SRL;
|
||||||
|
} else if (i.funct7 == 0b0000001) {
|
||||||
|
i.op = Op::DIVU;
|
||||||
|
} else if (i.funct7 == 0b0100000) {
|
||||||
|
i.op = Op::SRA;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 1: funct3=0b101: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b110) {
|
||||||
|
if (i.funct7 == 0b0000001) {
|
||||||
|
i.op = Op::REM;
|
||||||
|
} else if (i.funct7 == 0b0000000) {
|
||||||
|
i.op = Op::OR;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 1: funct3=0b110: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b111) {
|
||||||
|
if (i.funct7 == 0b000) {
|
||||||
|
i.op = Op::AND;
|
||||||
|
} else if (i.funct7 == 0b001) {
|
||||||
|
i.op = Op::REMU;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 1: funct3=0b111: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "R-type 1: unrecognized funct3: {:03b}", i.funct3);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 0b0101111:
|
case 0b0101111:
|
||||||
std::println(stderr, "A extension not implemented yet.");
|
std::println(stderr, "A extension not implemented yet.");
|
||||||
exit(1);
|
exit(1);
|
||||||
case 0b0110011:
|
|
||||||
case 0b0111011: {
|
case 0b0111011: {
|
||||||
u8 rd = (ins >> 7) & 0b11111;
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
u8 funct3 = (ins >> 12) & 0b111;
|
i.funct3 = (raw >> 12) & 0b111;
|
||||||
u8 rs1 = (ins >> 15) & 0b11111;
|
i.rs1 = (raw >> 15) & 0b11111;
|
||||||
u8 rs2 = (ins >> 20) & 0b11111;
|
i.rs2 = (raw >> 20) & 0b11111;
|
||||||
u8 funct7 = (u8)((ins >> 25) & 0b1111111);
|
i.funct7 = (u8)((raw >> 25) & 0b1111111);
|
||||||
|
|
||||||
return Ins{.opcode = opcode,
|
if (i.funct3 == 0b000) {
|
||||||
.rd = rd,
|
if (i.funct7 == 0b0000000) {
|
||||||
.funct3 = funct3,
|
i.op = Op::ADDW;
|
||||||
.rs1 = rs1,
|
} else if (i.funct7 == 0b0100000) {
|
||||||
.rs2 = rs2,
|
i.op = Op::SUBW;
|
||||||
.funct7 = funct7};
|
} else if (i.funct7 == 0b0000001) {
|
||||||
|
i.op = Op::MULW;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 3: funct3=000: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b001) {
|
||||||
|
i.op = Op::SLLW;
|
||||||
|
} else if (i.funct3 == 0b100) {
|
||||||
|
i.op = Op::DIVW;
|
||||||
|
} else if (i.funct3 == 0b101) {
|
||||||
|
if (i.funct7 == 0b0000000) {
|
||||||
|
i.op = Op::SRLW;
|
||||||
|
} else if (i.funct7 == 0b0100000) {
|
||||||
|
i.op = Op::SRAW;
|
||||||
|
} else if (i.funct7 == 0b0000001) {
|
||||||
|
i.op = Op::DIVUW;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 3: funct3=101: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else if (i.funct3 == 0b110) {
|
||||||
|
i.op = Op::REMW;
|
||||||
|
} else if (i.funct3 == 0b111) {
|
||||||
|
i.op = Op::REMUW;
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "R-type 3: unrecognized funct3: {:03b}", i.funct3);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 0b0011011: {
|
case 0b0011011: {
|
||||||
u8 rd = (ins >> 7) & 0b11111;
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
u8 funct3 = (ins >> 12) & 0b111;
|
i.funct3 = (raw >> 12) & 0b111;
|
||||||
u8 rs1 = (ins >> 15) & 0b11111;
|
i.rs1 = (raw >> 15) & 0b11111;
|
||||||
u8 rs2 = (ins >> 20) & 0b11111;
|
i.imm = ((i32)raw) >> 20;
|
||||||
u8 funct7 = (u8)((ins >> 25) & 0b1111111);
|
i.shamt = (raw >> 20) & 0b11111;
|
||||||
u8 shamt = (ins >> 20) & 0b11111;
|
i.funct7 = (raw >> 25) & 0b1111111;
|
||||||
i32 imm = ((i32)ins) >> 20;
|
|
||||||
|
|
||||||
return Ins{.opcode = opcode,
|
if (i.funct3 == 0b000) {
|
||||||
.rd = rd,
|
i.op = Op::ADDIW;
|
||||||
.funct3 = funct3,
|
} else if (i.funct3 == 0b001) {
|
||||||
.rs1 = rs1,
|
i.op = Op::SLLIW;
|
||||||
.rs2 = rs2,
|
} else if (i.funct3 == 0b101) {
|
||||||
.funct7 = funct7,
|
if (i.funct7 == 0b0000000) {
|
||||||
.shamt = shamt,
|
i.op = Op::SRLIW;
|
||||||
.imm = imm};
|
} else if (i.funct7 == 0b0100000) {
|
||||||
|
i.op = Op::SRAIW;
|
||||||
|
} else {
|
||||||
|
std::println(stderr,
|
||||||
|
"R-type 4: funct3=101: unrecognized funct7: {:b}",
|
||||||
|
i.funct7);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "R-type 4: unrecognized funct3: {:03b}", i.funct3);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case 0b0000111: {
|
case 0b0000111: {
|
||||||
std::println(stderr, "F extension not implemented yet.");
|
std::println(stderr, "F extension not implemented yet.");
|
||||||
@@ -1040,31 +1349,43 @@ private:
|
|||||||
exit(1);
|
exit(1);
|
||||||
}; break;
|
}; break;
|
||||||
case 0b0100011: {
|
case 0b0100011: {
|
||||||
u8 funct3 = (ins >> 12) & 0b111;
|
i.funct3 = (raw >> 12) & 0b111;
|
||||||
u8 rs1 = (ins >> 15) & 0b11111;
|
i.rs1 = (raw >> 15) & 0b11111;
|
||||||
u8 rs2 = (ins >> 20) & 0b11111;
|
i.rs2 = (raw >> 20) & 0b11111;
|
||||||
i32 imm_11_5 = (ins >> 25) & 0b1111111;
|
i32 imm_11_5 = (raw >> 25) & 0b1111111;
|
||||||
i32 imm_4_0 = (ins >> 7) & 0b11111;
|
i32 imm_4_0 = (raw >> 7) & 0b11111;
|
||||||
i32 imm = (imm_11_5 << 5) | imm_4_0;
|
i.imm = (imm_11_5 << 5) | imm_4_0;
|
||||||
imm = (imm << 20) >> 20;
|
i.imm = (i.imm << 20) >> 20;
|
||||||
|
|
||||||
return Ins{.opcode = opcode,
|
if (i.funct3 == 0b000) {
|
||||||
.funct3 = funct3,
|
i.op = Op::SB;
|
||||||
.rs1 = rs1,
|
} else if (i.funct3 == 0b001) {
|
||||||
.rs2 = rs2,
|
i.op = Op::SH;
|
||||||
.imm = imm};
|
} else if (i.funct3 == 0b010) {
|
||||||
|
i.op = Op::SW;
|
||||||
|
} else if (i.funct3 == 0b011) {
|
||||||
|
i.op = Op::SD;
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "S-type: unrecognized funct3: {:03b}", i.funct3);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case 0b0110111: {
|
||||||
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
|
i.imm = raw >> 12;
|
||||||
|
i.op = Op::LUI;
|
||||||
}; break;
|
}; break;
|
||||||
case 0b0110111:
|
|
||||||
case 0b0010111: {
|
case 0b0010111: {
|
||||||
u8 rd = (ins >> 7) & 0b11111;
|
i.rd = (raw >> 7) & 0b11111;
|
||||||
i32 imm = ins >> 12;
|
i.imm = raw >> 12;
|
||||||
|
i.op = Op::AUIPC;
|
||||||
return Ins{.opcode = opcode, .rd = rd, .imm = imm};
|
|
||||||
}; break;
|
}; break;
|
||||||
default:
|
default:
|
||||||
std::println(stderr, "Unrecognized opcode: {:07b}", opcode);
|
std::println(stderr, "Unrecognized opcode: {:07b}", opcode);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user