Compare commits
2 Commits
20d8953220
...
4c7073657f
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c7073657f | |||
| 2252e1fa75 |
399
riscv64.cc
399
riscv64.cc
@@ -80,9 +80,9 @@ enum Op {
|
||||
C_OR,
|
||||
C_SD,
|
||||
C_SDSP,
|
||||
C_SLLI,
|
||||
C_SRAI,
|
||||
C_SRLI,
|
||||
C_SLLI,
|
||||
C_SUB,
|
||||
C_SUBW,
|
||||
C_SW,
|
||||
@@ -103,6 +103,7 @@ enum Op {
|
||||
LH,
|
||||
LHU,
|
||||
LR_D,
|
||||
LR_W,
|
||||
LUI,
|
||||
LW,
|
||||
LWU,
|
||||
@@ -119,6 +120,7 @@ enum Op {
|
||||
REMW,
|
||||
SB,
|
||||
SC_D,
|
||||
SC_W,
|
||||
SD,
|
||||
SH,
|
||||
SLL,
|
||||
@@ -171,6 +173,7 @@ enum class Format {
|
||||
I_SHIFT,
|
||||
S,
|
||||
B,
|
||||
CB,
|
||||
U,
|
||||
J,
|
||||
CI,
|
||||
@@ -188,57 +191,109 @@ struct OpDef {
|
||||
Format format;
|
||||
};
|
||||
|
||||
static constexpr std::array<OpDef, 101> OP_TABLE = {{
|
||||
{"???", Format::NONE}, {"add", Format::R},
|
||||
{"addi", Format::I}, {"addiw", Format::I},
|
||||
{"addw", Format::R}, {"amoswap.d", Format::R_ATOMIC},
|
||||
{"and", Format::R}, {"andi", Format::I},
|
||||
{"auipc", Format::U}, {"beq", Format::B},
|
||||
{"bge", Format::B}, {"bgeu", Format::B},
|
||||
{"blt", Format::B}, {"bltu", Format::B},
|
||||
{"bne", Format::B}, {"c.add", Format::CR},
|
||||
{"c.addi", Format::CI}, {"c.addiw", Format::CI},
|
||||
{"c.addi16sp", Format::CI}, {"c.addi4spn", Format::CI},
|
||||
{"c.addw", Format::CI}, {"c.and", Format::CR},
|
||||
{"c.andi", Format::CI}, {"c.beqz", Format::B},
|
||||
{"c.bnez", Format::B}, {"c.ebreak", Format::CR},
|
||||
{"c.fldsp", Format::CSS}, {"c.j", Format::CJ},
|
||||
{"c.jalr", Format::CR1}, {"c.jr", Format::CR1},
|
||||
{"c.ld", Format::CL}, {"c.ldsp", Format::CL},
|
||||
{"c.li", Format::CI}, {"c.lui", Format::CI},
|
||||
{"c.lw", Format::CL}, {"c.mv", Format::CR},
|
||||
{"c.or", Format::CR}, {"c.sd", Format::S},
|
||||
{"c.sdsp", Format::CSS}, {"c.slli", Format::CI},
|
||||
{"c.srai", Format::CI}, {"c.srli", Format::CI},
|
||||
{"c.sub", Format::CR}, {"c.subw", Format::CR},
|
||||
{"c.sw", Format::S}, {"c.swsp", Format::CSS},
|
||||
{"c.xor", Format::CR}, {"div", Format::R},
|
||||
{"divu", Format::R}, {"divuw", Format::R},
|
||||
{"divw", Format::R}, {"ecall", Format::NONE},
|
||||
{"fence", Format::NONE}, {"fence.tso", Format::NONE},
|
||||
{"jal", Format::J}, {"jalr", Format::I},
|
||||
{"lb", Format::I_LOAD}, {"lbu", Format::I_LOAD},
|
||||
{"ld", Format::I_LOAD}, {"lh", Format::I_LOAD},
|
||||
{"lhu", Format::I_LOAD}, {"lr.d", Format::R_ATOMIC_LR},
|
||||
{"lui", Format::U}, {"lw", Format::I_LOAD},
|
||||
{"lwu", Format::I_LOAD}, {"mul", Format::R},
|
||||
{"mulh", Format::R}, {"mulhu", Format::R},
|
||||
{"mulw", Format::R}, {"or", Format::R},
|
||||
{"ori", Format::I}, {"pause", Format::NONE},
|
||||
{"rem", Format::R}, {"remu", Format::R},
|
||||
{"remuw", Format::R}, {"remw", Format::R},
|
||||
{"sb", Format::S}, {"sc.d", Format::R_ATOMIC},
|
||||
{"sd", Format::S}, {"sh", Format::S},
|
||||
{"sll", Format::R}, {"slli", Format::I_SHIFT},
|
||||
{"slliw", Format::I_SHIFT}, {"sllw", Format::R},
|
||||
{"slt", Format::R}, {"slti", Format::I},
|
||||
{"sltiu", Format::I}, {"sltu", Format::R},
|
||||
{"sra", Format::R}, {"srai", Format::I_SHIFT},
|
||||
{"sraiw", Format::I_SHIFT}, {"sraw", Format::R},
|
||||
{"srl", Format::R}, {"srli", Format::I_SHIFT},
|
||||
{"srliw", Format::I_SHIFT}, {"srlw", Format::R},
|
||||
{"sub", Format::R}, {"subw", Format::R},
|
||||
{"sw", Format::S}, {"xor", Format::R},
|
||||
static constexpr std::array<OpDef, 103> OP_TABLE = {{
|
||||
{"???", Format::NONE},
|
||||
{"add", Format::R},
|
||||
{"addi", Format::I},
|
||||
{"addiw", Format::I},
|
||||
{"addw", Format::R},
|
||||
{"amoswap.d", Format::R_ATOMIC},
|
||||
{"and", Format::R},
|
||||
{"andi", Format::I},
|
||||
{"auipc", Format::U},
|
||||
{"beq", Format::B},
|
||||
{"bge", Format::B},
|
||||
{"bgeu", Format::B},
|
||||
{"blt", Format::B},
|
||||
{"bltu", Format::B},
|
||||
{"bne", Format::B},
|
||||
{"c.add", Format::CR},
|
||||
{"c.addi", Format::CI},
|
||||
{"c.addiw", Format::CI},
|
||||
{"c.addi16sp", Format::CI},
|
||||
{"c.addi4spn", Format::CI},
|
||||
{"c.addw", Format::CR},
|
||||
{"c.and", Format::CR},
|
||||
{"c.andi", Format::CI},
|
||||
{"c.beqz", Format::CB},
|
||||
{"c.bnez", Format::CB},
|
||||
{"c.ebreak", Format::NONE},
|
||||
{"c.fldsp", Format::CSS},
|
||||
{"c.j", Format::CJ},
|
||||
{"c.jalr", Format::CR1},
|
||||
{"c.jr", Format::CR1},
|
||||
{"c.ld", Format::CL},
|
||||
{"c.ldsp", Format::CL},
|
||||
{"c.li", Format::CI},
|
||||
{"c.lui", Format::CI},
|
||||
{"c.lw", Format::CL},
|
||||
{"c.mv", Format::CR},
|
||||
{"c.or", Format::CR},
|
||||
{"c.sd", Format::S},
|
||||
{"c.sdsp", Format::CSS},
|
||||
{"c.slli", Format::CI},
|
||||
{"c.srai", Format::CI},
|
||||
{"c.srli", Format::CI},
|
||||
{"c.sub", Format::CR},
|
||||
{"c.subw", Format::CR},
|
||||
{"c.sw", Format::S},
|
||||
{"c.swsp", Format::CSS},
|
||||
{"c.xor", Format::CR},
|
||||
{"div", Format::R},
|
||||
{"divu", Format::R},
|
||||
{"divuw", Format::R},
|
||||
{"divw", Format::R},
|
||||
{"ecall", Format::NONE},
|
||||
{"fence", Format::NONE},
|
||||
{"fence.tso", Format::NONE},
|
||||
{"jal", Format::J},
|
||||
{"jalr", Format::I},
|
||||
{"lb", Format::I_LOAD},
|
||||
{"lbu", Format::I_LOAD},
|
||||
{"ld", Format::I_LOAD},
|
||||
{"lh", Format::I_LOAD},
|
||||
{"lhu", Format::I_LOAD},
|
||||
{"lr.d", Format::R_ATOMIC_LR},
|
||||
{"lr.w", Format::R_ATOMIC_LR},
|
||||
{"lui", Format::U},
|
||||
{"lw", Format::I_LOAD},
|
||||
{"lwu", Format::I_LOAD},
|
||||
{"mul", Format::R},
|
||||
{"mulh", Format::R},
|
||||
{"mulhu", Format::R},
|
||||
{"mulw", Format::R},
|
||||
{"or", Format::R},
|
||||
{"ori", Format::I},
|
||||
{"pause", Format::NONE},
|
||||
{"rem", Format::R},
|
||||
{"remu", Format::R},
|
||||
{"remuw", Format::R},
|
||||
{"remw", Format::R},
|
||||
{"sb", Format::S},
|
||||
{"sc.d", Format::R_ATOMIC},
|
||||
{"sc.w", Format::R_ATOMIC},
|
||||
{"sd", Format::S},
|
||||
{"sh", Format::S},
|
||||
{"sll", Format::R},
|
||||
{"slli", Format::I_SHIFT},
|
||||
{"slliw", Format::I_SHIFT},
|
||||
{"sllw", Format::R},
|
||||
{"slt", Format::R},
|
||||
{"slti", Format::I},
|
||||
{"sltiu", Format::I},
|
||||
{"sltu", Format::R},
|
||||
{"sra", Format::R},
|
||||
{"srai", Format::I_SHIFT},
|
||||
{"sraiw", Format::I_SHIFT},
|
||||
{"sraw", Format::R},
|
||||
{"srl", Format::R},
|
||||
{"srli", Format::I_SHIFT},
|
||||
{"srliw", Format::I_SHIFT},
|
||||
{"srlw", Format::R},
|
||||
{"sub", Format::R},
|
||||
{"subw", Format::R},
|
||||
{"sw", Format::S},
|
||||
{"xor", Format::R},
|
||||
{"xori", Format::I},
|
||||
}};
|
||||
|
||||
@@ -334,6 +389,9 @@ public:
|
||||
std::println("{} {}, {}, {}", def.mnemonic, REGS[ins.rs1], REGS[ins.rs2],
|
||||
ins.imm);
|
||||
break;
|
||||
case Format::CB:
|
||||
std::println("{} {}, {}", def.mnemonic, REGS[ins.rs1], ins.imm);
|
||||
break;
|
||||
case Format::J:
|
||||
std::println("{} {}, {}", def.mnemonic, REGS[ins.rd], ins.imm);
|
||||
break;
|
||||
@@ -452,8 +510,10 @@ public:
|
||||
}
|
||||
}; break;
|
||||
case Op::BGEU: {
|
||||
std::println(stderr, "BGEU unimplemented");
|
||||
exit(1);
|
||||
if ((u64)m_regs[i.rs1] >= (u64)m_regs[i.rs2]) {
|
||||
m_pc += i.imm;
|
||||
continue;
|
||||
}
|
||||
}; break;
|
||||
case Op::BLT: {
|
||||
if (m_regs[i.rs1] < m_regs[i.rs2]) {
|
||||
@@ -473,6 +533,95 @@ public:
|
||||
continue;
|
||||
}
|
||||
}; break;
|
||||
case Op::C_ADD: {
|
||||
m_regs[i.rd] += m_regs[i.rs2];
|
||||
}; break;
|
||||
case Op::C_ADDI: {
|
||||
m_regs[i.rd] += i.imm;
|
||||
}; break;
|
||||
case Op::C_ADDIW: {
|
||||
m_regs[i.rd] = (i64)(i32)m_regs[i.rd] + i.imm;
|
||||
}; break;
|
||||
case Op::C_ADDI16SP: {
|
||||
sp += i.imm;
|
||||
}; break;
|
||||
case Op::C_ADDI4SPN: {
|
||||
m_regs[i.rd] = sp + i.imm;
|
||||
}; break;
|
||||
case Op::C_ADDW: {
|
||||
m_regs[i.rd] = (i64)((i32)m_regs[i.rd] + (i32)m_regs[i.rs2]);
|
||||
}; break;
|
||||
case Op::C_AND: {
|
||||
m_regs[i.rd] &= m_regs[i.rs2];
|
||||
}; break;
|
||||
case Op::C_ANDI: {
|
||||
m_regs[i.rd] = m_regs[i.rs1] & i.imm;
|
||||
}; break;
|
||||
case Op::C_BEQZ: {
|
||||
if (m_regs[i.rs1] == 0) {
|
||||
m_pc += i.imm;
|
||||
continue;
|
||||
}
|
||||
}; break;
|
||||
case Op::C_BNEZ: {
|
||||
if (m_regs[i.rs1] != 0) {
|
||||
m_pc += i.imm;
|
||||
continue;
|
||||
}
|
||||
}; break;
|
||||
case Op::C_J: {
|
||||
m_pc += i.imm;
|
||||
continue;
|
||||
}; break;
|
||||
case Op::C_JALR: {
|
||||
m_regs[1] = m_pc + 2;
|
||||
m_pc = m_regs[i.rs1];
|
||||
continue;
|
||||
}; break;
|
||||
case Op::C_JR: {
|
||||
m_pc = m_regs[i.rs1];
|
||||
continue;
|
||||
}; break;
|
||||
case Op::C_LD: {
|
||||
u64 addr = m_regs[i.rs1] + i.imm;
|
||||
m_regs[i.rd] = *(u64 *)&m_memory[addr];
|
||||
}; break;
|
||||
case Op::C_LDSP: {
|
||||
u64 addr = sp + i.imm;
|
||||
m_regs[i.rd] = *(u64 *)(&m_memory[addr]);
|
||||
}; break;
|
||||
case Op::C_LI: {
|
||||
m_regs[i.rd] = i.imm;
|
||||
}; break;
|
||||
case Op::C_LUI: {
|
||||
m_regs[i.rd] = (int64_t)(uint64_t)((int64_t)i.imm) << 12;
|
||||
}; break;
|
||||
case Op::C_LW: {
|
||||
u64 addr = m_regs[i.rs1] + i.imm;
|
||||
m_regs[i.rd] = *(u32 *)&m_memory[addr];
|
||||
}; break;
|
||||
case Op::C_MV: {
|
||||
m_regs[i.rd] = m_regs[i.rs2];
|
||||
}; break;
|
||||
case Op::C_OR: {
|
||||
m_regs[i.rd] |= m_regs[i.rs2];
|
||||
}; break;
|
||||
case Op::C_SDSP: {
|
||||
u64 addr = sp + i.imm;
|
||||
*(u64 *)(&m_memory[addr]) = m_regs[i.rs2];
|
||||
}; break;
|
||||
case Op::C_SLLI: {
|
||||
m_regs[i.rd] = (i64)((u64)m_regs[i.rd] << i.imm);
|
||||
}; break;
|
||||
case Op::C_SRAI: {
|
||||
m_regs[i.rd] >>= i.imm;
|
||||
}; break;
|
||||
case Op::C_SRLI: {
|
||||
m_regs[i.rd] = (i64)((u64)m_regs[i.rd] >> i.imm);
|
||||
}; break;
|
||||
case Op::C_SUB: {
|
||||
m_regs[i.rd] -= m_regs[i.rs2];
|
||||
}; break;
|
||||
case Op::DIV: {
|
||||
if (m_regs[i.rs2] == 0) {
|
||||
m_regs[i.rd] = -1;
|
||||
@@ -480,10 +629,6 @@ public:
|
||||
m_regs[i.rd] = m_regs[i.rs1] / m_regs[i.rs2];
|
||||
}
|
||||
}; break;
|
||||
case Op::DIVU: {
|
||||
std::println(stderr, "DIVU unimplemented");
|
||||
exit(1);
|
||||
}; break;
|
||||
case Op::DIVUW: {
|
||||
if (m_regs[i.rs2] == 0) {
|
||||
m_regs[i.rd] = -1LL;
|
||||
@@ -505,21 +650,38 @@ public:
|
||||
case Op::ECALL: {
|
||||
// https://jborza.com/post/2021-05-11-riscv-linux-syscalls/
|
||||
switch (m_regs[17]) {
|
||||
case 29: { // ioctl
|
||||
u32 fd = m_regs[10];
|
||||
u32 cmd = m_regs[11];
|
||||
u64 arg = m_regs[12];
|
||||
|
||||
switch (cmd) {
|
||||
case 0x5413: { // TIOCGWINSZ
|
||||
m_regs[10] = -ENOTTY;
|
||||
}; break;
|
||||
default: {
|
||||
std::println(stderr, "ioctl(fd={}, cmd={}, arg={}) unimplemented",
|
||||
fd, cmd, arg);
|
||||
exit(1);
|
||||
}; break;
|
||||
}
|
||||
}; break;
|
||||
case 63: { // read
|
||||
if (m_regs[10] != 0) {
|
||||
u32 fd = m_regs[10];
|
||||
u64 buf = m_regs[11];
|
||||
u64 count = m_regs[12];
|
||||
|
||||
if (fd != 0) {
|
||||
std::println(stderr, "read syscall implemented only for stdin.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
u64 start = m_regs[11];
|
||||
u64 count = m_regs[12];
|
||||
u64 bytes_read = 0;
|
||||
|
||||
for (u64 i = 0; i < count; i++) {
|
||||
char c;
|
||||
if (!std::cin.get(c))
|
||||
break;
|
||||
m_memory[start + i] = (u8)c;
|
||||
m_memory[buf + i] = (u8)c;
|
||||
bytes_read++;
|
||||
if (c == '\n')
|
||||
break;
|
||||
@@ -528,22 +690,58 @@ public:
|
||||
m_regs[10] = bytes_read;
|
||||
}; break;
|
||||
case 64: { // write
|
||||
if (m_regs[10] != 1) {
|
||||
u32 fd = m_regs[10];
|
||||
u64 buf = m_regs[11];
|
||||
u64 count = m_regs[12];
|
||||
|
||||
if (fd != 1) {
|
||||
std::println(stderr, "write syscall implemented only for stdout.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
u64 start = m_regs[11];
|
||||
u64 end = m_regs[11] + m_regs[12];
|
||||
|
||||
for (u64 i = start; i < end; i++) {
|
||||
u64 end = buf + count;
|
||||
for (u64 i = buf; i < end; i++) {
|
||||
std::cout.put(m_memory[i]);
|
||||
}
|
||||
|
||||
m_regs[10] = count;
|
||||
}; break;
|
||||
case 93: { // exit
|
||||
case 66: { // writev
|
||||
u32 fd = m_regs[10];
|
||||
u64 vec = m_regs[11];
|
||||
u64 vlen = m_regs[12];
|
||||
|
||||
if (fd != 1) {
|
||||
std::println(stderr, "writev syscall implemented only for stdout.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
u64 total_written = 0;
|
||||
for (u64 i = 0; i < vlen; i++) {
|
||||
u64 iov_entry = vec + i * 16;
|
||||
u64 buf = *(u64 *)&m_memory[iov_entry];
|
||||
u64 len = *(u64 *)&m_memory[iov_entry + 8];
|
||||
|
||||
for (u64 j = 0; j < len; j++) {
|
||||
std::cout.put(m_memory[buf + j]);
|
||||
}
|
||||
total_written += len;
|
||||
}
|
||||
|
||||
m_regs[10] = total_written;
|
||||
} break;
|
||||
|
||||
case 93: // exit
|
||||
case 94: { // exit_group
|
||||
std::println("Program exited with code {}.", m_regs[10]);
|
||||
return;
|
||||
}; break;
|
||||
case 96: { // set_tid_address
|
||||
i64 tidptr = m_regs[10];
|
||||
i32 tid = 123;
|
||||
memcpy(&m_memory[tidptr], &tid, sizeof(tid));
|
||||
m_regs[10] = tid;
|
||||
}; break;
|
||||
case 169: { // gettimeofday
|
||||
i64 tv_addr = m_regs[10];
|
||||
i64 tz_addr = m_regs[11];
|
||||
@@ -590,20 +788,12 @@ public:
|
||||
case Op::LH: {
|
||||
m_regs[i.rd] = *(i16 *)&m_memory[m_regs[i.rs1] + i.imm];
|
||||
}; break;
|
||||
case Op::LHU: {
|
||||
std::println(stderr, "LHU unimplemented");
|
||||
exit(1);
|
||||
}; break;
|
||||
case Op::LUI: {
|
||||
m_regs[i.rd] = (i64)(i32)(i.imm << 12);
|
||||
}; break;
|
||||
case Op::LW: {
|
||||
m_regs[i.rd] = *(i32 *)&m_memory[m_regs[i.rs1] + i.imm];
|
||||
}; break;
|
||||
case Op::LWU: {
|
||||
std::println(stderr, "LWU unimplemented");
|
||||
exit(1);
|
||||
}; break;
|
||||
case Op::MUL: {
|
||||
m_regs[i.rd] = m_regs[i.rs1] * m_regs[i.rs2];
|
||||
}; break;
|
||||
@@ -640,10 +830,6 @@ public:
|
||||
case Op::OR: {
|
||||
m_regs[i.rd] = m_regs[i.rs1] | m_regs[i.rs2];
|
||||
}; break;
|
||||
case Op::ORI: {
|
||||
std::println(stderr, "ORI unimplemented");
|
||||
exit(1);
|
||||
}; break;
|
||||
case Op::REM: {
|
||||
if (m_regs[i.rs2] == 0) {
|
||||
m_regs[i.rd] = m_regs[i.rs1];
|
||||
@@ -665,15 +851,12 @@ public:
|
||||
m_regs[i.rd] = (i32)((u32)m_regs[i.rs1] % (u32)m_regs[i.rs2]);
|
||||
}
|
||||
}; break;
|
||||
case Op::REMW: {
|
||||
std::println(stderr, "REMW unimplemented");
|
||||
exit(1);
|
||||
}; break;
|
||||
case Op::SB: {
|
||||
u64 addr = m_regs[i.rs1] + i.imm;
|
||||
m_memory[addr] = m_regs[i.rs2];
|
||||
}; break;
|
||||
case Op::SD: {
|
||||
case Op::SD:
|
||||
case Op::C_SD: {
|
||||
u64 addr = m_regs[i.rs1] + i.imm;
|
||||
*(u64 *)(&m_memory[addr]) = m_regs[i.rs2];
|
||||
}; break;
|
||||
@@ -681,10 +864,6 @@ public:
|
||||
u64 addr = m_regs[i.rs1] + i.imm;
|
||||
*(u16 *)(&m_memory[addr]) = m_regs[i.rs2];
|
||||
}; break;
|
||||
case Op::SLL: {
|
||||
std::println(stderr, "SLL unimplemented");
|
||||
exit(1);
|
||||
}; break;
|
||||
case Op::SLLI: {
|
||||
m_regs[i.rd] = m_regs[i.rs1] << i.shamt;
|
||||
}; break;
|
||||
@@ -698,20 +877,12 @@ public:
|
||||
case Op::SLT: {
|
||||
m_regs[i.rd] = (m_regs[i.rs1] < m_regs[i.rs2]) ? 1 : 0;
|
||||
}; break;
|
||||
case Op::SLTI: {
|
||||
std::println(stderr, "SLTI unimplemented");
|
||||
exit(1);
|
||||
}; break;
|
||||
case Op::SLTIU: {
|
||||
m_regs[i.rd] = ((u64)m_regs[i.rs1] < (u64)(i64)i.imm) ? 1 : 0;
|
||||
}; break;
|
||||
case Op::SLTU: {
|
||||
m_regs[i.rd] = ((u64)m_regs[i.rs1] < (u64)m_regs[i.rs2]) ? 1 : 0;
|
||||
}; break;
|
||||
case Op::SRA: {
|
||||
std::println(stderr, "SRA unimplemented");
|
||||
exit(1);
|
||||
}; break;
|
||||
case Op::SRAI: {
|
||||
m_regs[i.rd] = (i64)m_regs[i.rs1] >> i.shamt;
|
||||
}; break;
|
||||
@@ -721,10 +892,6 @@ public:
|
||||
case Op::SRAW: {
|
||||
m_regs[i.rd] = ((i32)m_regs[i.rs1]) >> ((u32)m_regs[i.rs2] & 0b11111);
|
||||
}; break;
|
||||
case Op::SRL: {
|
||||
std::println(stderr, "SRL unimplemented");
|
||||
exit(1);
|
||||
}; break;
|
||||
case Op::SRLI: {
|
||||
m_regs[i.rd] = (u64)m_regs[i.rs1] >> i.shamt;
|
||||
}; break;
|
||||
@@ -741,6 +908,7 @@ public:
|
||||
case Op::SUBW: {
|
||||
m_regs[i.rd] = (i32)(m_regs[i.rs1] - m_regs[i.rs2]);
|
||||
}; break;
|
||||
case Op::C_SW:
|
||||
case Op::SW: {
|
||||
u64 addr = m_regs[i.rs1] + i.imm;
|
||||
*(u32 *)(&m_memory[addr]) = m_regs[i.rs2];
|
||||
@@ -752,7 +920,7 @@ public:
|
||||
m_regs[i.rd] = m_regs[i.rs1] ^ i.imm;
|
||||
}; break;
|
||||
default: {
|
||||
std::println(stderr, "Unrecognized Op: {}", (u64)i.op);
|
||||
std::println(stderr, "{} not implemented", OP_TABLE[i.op].mnemonic);
|
||||
exit(1);
|
||||
}; break;
|
||||
}
|
||||
@@ -885,16 +1053,17 @@ private:
|
||||
i.imm = (i.imm << 22) >> 22;
|
||||
i.op = Op::C_ADDI16SP;
|
||||
} else {
|
||||
i.imm = (((raw >> 12) & 0b1) << 17) | (((raw >> 2) & 0b11111) << 12);
|
||||
i.imm = (i.imm << 14) >> 14;
|
||||
i.imm = (((raw >> 12) & 0b1) << 5) | ((raw >> 2) & 0b11111);
|
||||
i.imm = (i.imm << 26) >> 26;
|
||||
i.op = Op::C_LUI;
|
||||
}
|
||||
|
||||
}; break;
|
||||
case 0b100: {
|
||||
u8 funct2 = (raw >> 10) & 0b11;
|
||||
|
||||
if (funct2 == 0b11) {
|
||||
i.rs1 = ((raw >> 7) & 0b111) + 8;
|
||||
i.rd = i.rs1;
|
||||
|
||||
bool bit12 = (raw >> 12) & 0b1;
|
||||
i.rs2 = ((raw >> 2) & 0b111) + 8;
|
||||
@@ -1325,7 +1494,22 @@ private:
|
||||
i.rs1 = (raw >> 15) & 0b11111;
|
||||
i.rs2 = (raw >> 20) & 0b11111;
|
||||
|
||||
if (funct3 == 0b011) {
|
||||
if (funct3 == 0b010) {
|
||||
switch (funct7) {
|
||||
case 0b00010: {
|
||||
i.op = Op::LR_W;
|
||||
}; break;
|
||||
case 0b00011: {
|
||||
i.op = Op::SC_W;
|
||||
}; break;
|
||||
default: {
|
||||
std::println(stderr,
|
||||
"0101111: funct3=010: unrecognized funct7: {:05b}",
|
||||
funct7);
|
||||
exit(1);
|
||||
}; break;
|
||||
}
|
||||
} else if (funct3 == 0b011) {
|
||||
switch (funct7) {
|
||||
case 0b00001: {
|
||||
i.op = Op::AMOSWAP_D;
|
||||
@@ -1522,7 +1706,6 @@ int main(int argc, char *argv[]) {
|
||||
exe_bytes.clear();
|
||||
exe_bytes.shrink_to_fit();
|
||||
|
||||
r.disassemble_all();
|
||||
std::println("END DISASSEMBLY");
|
||||
|
||||
r.execute();
|
||||
|
||||
Reference in New Issue
Block a user