mirror of
https://github.com/liuk7071/ChonkyStation.git
synced 2024-05-20 12:57:52 -04:00
[CPU] Fix UB
This commit is contained in:
parent
6b6867262a
commit
366a9fa418
|
@ -22,34 +22,34 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
core->isDelaySlot = true;
|
||||
}
|
||||
|
||||
switch ((CpuCore::Opcode)instr.primaryOpc.Value()) {
|
||||
case CpuCore::Opcode::SPECIAL: {
|
||||
switch ((CpuCore::SPECIALOpcode)instr.secondaryOpc.Value()) {
|
||||
case CpuCore::SPECIALOpcode::SLL: {
|
||||
switch (instr.primaryOpc) {
|
||||
case CpuOpcodes::Opcode::SPECIAL: {
|
||||
switch (instr.secondaryOpc) {
|
||||
case CpuOpcodes::SPECIALOpcode::SLL: {
|
||||
gprs[instr.rd] = gprs[instr.rt] << instr.shiftImm;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SRL: {
|
||||
case CpuOpcodes::SPECIALOpcode::SRL: {
|
||||
gprs[instr.rd] = gprs[instr.rt] >> instr.shiftImm;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SRA: {
|
||||
case CpuOpcodes::SPECIALOpcode::SRA: {
|
||||
gprs[instr.rd] = (s32)gprs[instr.rt] >> instr.shiftImm;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SLLV: {
|
||||
case CpuOpcodes::SPECIALOpcode::SLLV: {
|
||||
gprs[instr.rd] = gprs[instr.rt] << (gprs[instr.rs] & 0x1f);
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SRLV: {
|
||||
case CpuOpcodes::SPECIALOpcode::SRLV: {
|
||||
gprs[instr.rd] = gprs[instr.rt] >> (gprs[instr.rs] & 0x1f);
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SRAV: {
|
||||
case CpuOpcodes::SPECIALOpcode::SRAV: {
|
||||
gprs[instr.rd] = (s32)gprs[instr.rt] >> (gprs[instr.rs] & 0x1f);
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::JR: {
|
||||
case CpuOpcodes::SPECIALOpcode::JR: {
|
||||
const u32 addr = gprs[instr.rs];
|
||||
if (addr & 3) {
|
||||
Helpers::panic("Bad JR addr\n");
|
||||
|
@ -58,38 +58,38 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
core->branched = true;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::JALR: {
|
||||
case CpuOpcodes::SPECIALOpcode::JALR: {
|
||||
const u32 addr = gprs[instr.rs];
|
||||
if (addr & 3) {
|
||||
Helpers::panic("Bad JALR addr\n");
|
||||
}
|
||||
gprs[CpuCore::CpuReg::RA] = core->nextPc;
|
||||
gprs[CpuOpcodes::CpuReg::RA] = core->nextPc;
|
||||
core->nextPc = addr;
|
||||
core->branched = true;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SYSCALL: {
|
||||
case CpuOpcodes::SPECIALOpcode::SYSCALL: {
|
||||
core->pc -= 4;
|
||||
core->exception(CpuCore::Exception::SysCall);
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::MFHI: {
|
||||
case CpuOpcodes::SPECIALOpcode::MFHI: {
|
||||
gprs[instr.rd] = core->hi;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::MTHI: {
|
||||
case CpuOpcodes::SPECIALOpcode::MTHI: {
|
||||
core->hi = gprs[instr.rs];
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::MFLO: {
|
||||
case CpuOpcodes::SPECIALOpcode::MFLO: {
|
||||
gprs[instr.rd] = core->lo;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::MTLO: {
|
||||
case CpuOpcodes::SPECIALOpcode::MTLO: {
|
||||
core->lo = gprs[instr.rs];
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::MULT: {
|
||||
case CpuOpcodes::SPECIALOpcode::MULT: {
|
||||
s64 x = (s64)(s32)gprs[instr.rs];
|
||||
s64 y = (s64)(s32)gprs[instr.rt];
|
||||
u64 res = x * y;
|
||||
|
@ -97,7 +97,7 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
core->lo = res & 0xffffffff;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::MULTU: {
|
||||
case CpuOpcodes::SPECIALOpcode::MULTU: {
|
||||
u64 x = gprs[instr.rs];
|
||||
u64 y = gprs[instr.rt];
|
||||
u64 res = x * y;
|
||||
|
@ -105,7 +105,7 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
core->lo = res & 0xffffffff;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::DIV: {
|
||||
case CpuOpcodes::SPECIALOpcode::DIV: {
|
||||
const s32 n = (s32)gprs[instr.rs];
|
||||
const s32 d = (s32)gprs[instr.rt];
|
||||
|
||||
|
@ -126,7 +126,7 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
core->lo = n / d;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::DIVU: {
|
||||
case CpuOpcodes::SPECIALOpcode::DIVU: {
|
||||
const u32 n = gprs[instr.rs];
|
||||
const u32 d = gprs[instr.rt];
|
||||
|
||||
|
@ -139,45 +139,45 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
core->lo = n / d;
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::ADD: {
|
||||
case CpuOpcodes::SPECIALOpcode::ADD: {
|
||||
gprs[instr.rd] = gprs[instr.rs] + gprs[instr.rt];
|
||||
// TODO: overflow exception
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::ADDU: {
|
||||
case CpuOpcodes::SPECIALOpcode::ADDU: {
|
||||
gprs[instr.rd] = gprs[instr.rs] + gprs[instr.rt];
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SUB: {
|
||||
case CpuOpcodes::SPECIALOpcode::SUB: {
|
||||
gprs[instr.rd] = gprs[instr.rs] - gprs[instr.rt];
|
||||
// TODO: overflow exception
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SUBU: {
|
||||
case CpuOpcodes::SPECIALOpcode::SUBU: {
|
||||
gprs[instr.rd] = gprs[instr.rs] - gprs[instr.rt];
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::AND: {
|
||||
case CpuOpcodes::SPECIALOpcode::AND: {
|
||||
gprs[instr.rd] = gprs[instr.rs] & gprs[instr.rt];
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::OR: {
|
||||
case CpuOpcodes::SPECIALOpcode::OR: {
|
||||
gprs[instr.rd] = gprs[instr.rs] | gprs[instr.rt];
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::XOR: {
|
||||
case CpuOpcodes::SPECIALOpcode::XOR: {
|
||||
gprs[instr.rd] = gprs[instr.rs] ^ gprs[instr.rt];
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::NOR: {
|
||||
case CpuOpcodes::SPECIALOpcode::NOR: {
|
||||
gprs[instr.rd] = ~(gprs[instr.rs] | gprs[instr.rt]);
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SLT: {
|
||||
case CpuOpcodes::SPECIALOpcode::SLT: {
|
||||
gprs[instr.rd] = (s32)gprs[instr.rs] < (s32)gprs[instr.rt];
|
||||
break;
|
||||
}
|
||||
case CpuCore::SPECIALOpcode::SLTU: {
|
||||
case CpuOpcodes::SPECIALOpcode::SLTU: {
|
||||
gprs[instr.rd] = gprs[instr.rs] < gprs[instr.rt];
|
||||
break;
|
||||
}
|
||||
|
@ -186,32 +186,32 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::REGIMM: {
|
||||
switch ((CpuCore::REGIMMOpcode)instr.regimmOpc.Value()) {
|
||||
case CpuCore::REGIMMOpcode::BLTZ: {
|
||||
case CpuOpcodes::Opcode::REGIMM: {
|
||||
switch (instr.regimmOpc) {
|
||||
case CpuOpcodes::REGIMMOpcode::BLTZ: {
|
||||
if ((s32)gprs[instr.rs] < 0) {
|
||||
core->nextPc = core->pc + ((u32)(s16)instr.imm << 2);
|
||||
core->branched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::REGIMMOpcode::BGEZ: {
|
||||
case CpuOpcodes::REGIMMOpcode::BGEZ: {
|
||||
if ((s32)gprs[instr.rs] >= 0) {
|
||||
core->nextPc = core->pc + ((u32)(s16)instr.imm << 2);
|
||||
core->branched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::REGIMMOpcode::BLTZAL: {
|
||||
gprs[CpuCore::CpuReg::RA] = core->nextPc;
|
||||
case CpuOpcodes::REGIMMOpcode::BLTZAL: {
|
||||
gprs[CpuOpcodes::CpuReg::RA] = core->nextPc;
|
||||
if ((s32)gprs[instr.rs] < 0) {
|
||||
core->nextPc = core->pc + ((u32)(s16)instr.imm << 2);
|
||||
core->branched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::REGIMMOpcode::BGEZAL: {
|
||||
gprs[CpuCore::CpuReg::RA] = core->nextPc;
|
||||
case CpuOpcodes::REGIMMOpcode::BGEZAL: {
|
||||
gprs[CpuOpcodes::CpuReg::RA] = core->nextPc;
|
||||
if ((s32)gprs[instr.rs] >= 0) {
|
||||
core->nextPc = core->pc + ((u32)(s16)instr.imm << 2);
|
||||
core->branched = true;
|
||||
|
@ -223,91 +223,91 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::J: {
|
||||
case CpuOpcodes::Opcode::J: {
|
||||
core->nextPc = (core->pc & 0xf0000000) | (instr.jumpImm << 2);
|
||||
core->branched = true;
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::JAL: {
|
||||
gprs[CpuCore::CpuReg::RA] = core->nextPc;
|
||||
case CpuOpcodes::Opcode::JAL: {
|
||||
gprs[CpuOpcodes::CpuReg::RA] = core->nextPc;
|
||||
core->nextPc = (core->pc & 0xf0000000) | (instr.jumpImm << 2);
|
||||
core->branched = true;
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::BEQ: {
|
||||
case CpuOpcodes::Opcode::BEQ: {
|
||||
if (gprs[instr.rs] == gprs[instr.rt]) {
|
||||
core->nextPc = core->pc + ((u32)(s16)instr.imm << 2);
|
||||
core->branched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::BNE: {
|
||||
case CpuOpcodes::Opcode::BNE: {
|
||||
if (gprs[instr.rs] != gprs[instr.rt]) {
|
||||
core->nextPc = core->pc + ((u32)(s16)instr.imm << 2);
|
||||
core->branched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::BLEZ: {
|
||||
case CpuOpcodes::Opcode::BLEZ: {
|
||||
if ((s32)gprs[instr.rs] <= 0) {
|
||||
core->nextPc = core->pc + ((u32)(s16)instr.imm << 2);
|
||||
core->branched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::BGTZ: {
|
||||
case CpuOpcodes::Opcode::BGTZ: {
|
||||
if ((s32)gprs[instr.rs] > 0) {
|
||||
core->nextPc = core->pc + ((u32)(s16)instr.imm << 2);
|
||||
core->branched = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::ADDI: {
|
||||
case CpuOpcodes::Opcode::ADDI: {
|
||||
gprs[instr.rt] = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
// TODO: overflow exception
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::ADDIU: {
|
||||
case CpuOpcodes::Opcode::ADDIU: {
|
||||
gprs[instr.rt] = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::SLTI: {
|
||||
case CpuOpcodes::Opcode::SLTI: {
|
||||
gprs[instr.rt] = (s32)gprs[instr.rs] < (u32)(s16)instr.imm;
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::SLTIU: {
|
||||
case CpuOpcodes::Opcode::SLTIU: {
|
||||
gprs[instr.rt] = gprs[instr.rs] < instr.imm;
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::ANDI: {
|
||||
case CpuOpcodes::Opcode::ANDI: {
|
||||
gprs[instr.rt] = gprs[instr.rs] & instr.imm;
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::ORI: {
|
||||
case CpuOpcodes::Opcode::ORI: {
|
||||
gprs[instr.rt] = gprs[instr.rs] | instr.imm;
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::XORI: {
|
||||
case CpuOpcodes::Opcode::XORI: {
|
||||
gprs[instr.rt] = gprs[instr.rs] ^ instr.imm;
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::LUI: {
|
||||
case CpuOpcodes::Opcode::LUI: {
|
||||
gprs[instr.rt] = instr.imm << 16;
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::COP0: {
|
||||
switch ((CpuCore::COPOpcode)instr.cop0Opc.Value()) {
|
||||
case CpuCore::COPOpcode::MF: {
|
||||
case CpuOpcodes::Opcode::COP0: {
|
||||
switch (instr.cop0Opc) {
|
||||
case CpuOpcodes::COPOpcode::MF: {
|
||||
gprs[instr.rt] = core->cop0.read(instr.rd);
|
||||
break;
|
||||
}
|
||||
case CpuCore::COPOpcode::MT: {
|
||||
case CpuOpcodes::COPOpcode::MT: {
|
||||
core->cop0.write(instr.rd, gprs[instr.rt]);
|
||||
break;
|
||||
}
|
||||
case CpuCore::COPOpcode::CO: {
|
||||
switch ((CpuCore::COP0Opcode)instr.func.Value()) {
|
||||
case CpuCore::COP0Opcode::RFE: {
|
||||
case CpuOpcodes::COPOpcode::CO: {
|
||||
switch (instr.func) {
|
||||
case CpuOpcodes::COP0Opcode::RFE: {
|
||||
core->cop0.status.raw = (core->cop0.status.raw & 0xfffffff0) | ((core->cop0.status.raw & 0x3c) >> 2);
|
||||
break;
|
||||
}
|
||||
|
@ -321,12 +321,12 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::LB: {
|
||||
case CpuOpcodes::Opcode::LB: {
|
||||
const u32 addr = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
gprs[instr.rt] = (u32)(s8)mem->read<u8>(addr);
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::LH: {
|
||||
case CpuOpcodes::Opcode::LH: {
|
||||
const u32 addr = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
if (addr & 1) {
|
||||
Helpers::panic("Bad lh addr 0x%08x\n", addr);
|
||||
|
@ -334,7 +334,7 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
gprs[instr.rt] = (u32)(s16)mem->read<u16>(addr);
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::LW: {
|
||||
case CpuOpcodes::Opcode::LW: {
|
||||
const u32 addr = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
if (addr & 3) {
|
||||
Helpers::panic("Bad lw addr 0x%08x\n", addr);
|
||||
|
@ -342,12 +342,12 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
gprs[instr.rt] = mem->read<u32>(addr);
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::LBU: {
|
||||
case CpuOpcodes::Opcode::LBU: {
|
||||
const u32 addr = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
gprs[instr.rt] = mem->read<u8>(addr);
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::LHU: {
|
||||
case CpuOpcodes::Opcode::LHU: {
|
||||
const u32 addr = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
if (addr & 1) {
|
||||
Helpers::panic("Bad lhu addr 0x%08x\n", addr);
|
||||
|
@ -355,13 +355,13 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
gprs[instr.rt] = mem->read<u16>(addr);
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::SB: {
|
||||
case CpuOpcodes::Opcode::SB: {
|
||||
if (core->cop0.status.isc) return;
|
||||
const u32 addr = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
mem->write<u8>(addr, gprs[instr.rt]);
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::SH: {
|
||||
case CpuOpcodes::Opcode::SH: {
|
||||
if (core->cop0.status.isc) return;
|
||||
const u32 addr = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
if (addr & 1) {
|
||||
|
@ -370,7 +370,7 @@ void Interpreter::step(CpuCore* core, Memory* mem, Disassembler* disassembler) {
|
|||
mem->write<u16>(addr, gprs[instr.rt]);
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::SW: {
|
||||
case CpuOpcodes::Opcode::SW: {
|
||||
if (core->cop0.status.isc) break;
|
||||
const u32 addr = gprs[instr.rs] + (u32)(s16)instr.imm;
|
||||
if (addr & 3) {
|
||||
|
|
|
@ -148,101 +148,103 @@ public:
|
|||
pc = handler;
|
||||
nextPc = handler + 4;
|
||||
}
|
||||
};
|
||||
|
||||
enum CpuReg {
|
||||
R0 = 0, AT = 1, V0 = 2, V1 = 3,
|
||||
A0 = 4, A1 = 5, A2 = 6, A3 = 7,
|
||||
T0 = 8, T1 = 9, T2 = 10, T3 = 11,
|
||||
T4 = 12, T5 = 13, T6 = 14, T7 = 15,
|
||||
S0 = 16, S1 = 17, S2 = 18, S3 = 19,
|
||||
S4 = 20, S5 = 21, S6 = 22, S7 = 23,
|
||||
T8 = 24, T9 = 25, K0 = 26, K1 = 27,
|
||||
GP = 28, SP = 29, S8 = 30, RA = 31,
|
||||
LO = 32, HI = 33
|
||||
};
|
||||
namespace CpuOpcodes {
|
||||
enum CpuReg {
|
||||
R0 = 0, AT = 1, V0 = 2, V1 = 3,
|
||||
A0 = 4, A1 = 5, A2 = 6, A3 = 7,
|
||||
T0 = 8, T1 = 9, T2 = 10, T3 = 11,
|
||||
T4 = 12, T5 = 13, T6 = 14, T7 = 15,
|
||||
S0 = 16, S1 = 17, S2 = 18, S3 = 19,
|
||||
S4 = 20, S5 = 21, S6 = 22, S7 = 23,
|
||||
T8 = 24, T9 = 25, K0 = 26, K1 = 27,
|
||||
GP = 28, SP = 29, S8 = 30, RA = 31,
|
||||
LO = 32, HI = 33
|
||||
};
|
||||
|
||||
enum class Opcode {
|
||||
SPECIAL = 0x00,
|
||||
REGIMM = 0x01,
|
||||
J = 0x02,
|
||||
JAL = 0x03,
|
||||
BEQ = 0x04,
|
||||
BNE = 0x05,
|
||||
BLEZ = 0x06,
|
||||
BGTZ = 0x07,
|
||||
ADDI = 0x08,
|
||||
ADDIU = 0x09,
|
||||
SLTI = 0x0A,
|
||||
SLTIU = 0x0B,
|
||||
ANDI = 0x0C,
|
||||
ORI = 0x0D,
|
||||
XORI = 0x0E,
|
||||
LUI = 0x0F,
|
||||
COP0 = 0x10,
|
||||
COP2 = 0x12,
|
||||
LB = 0x20,
|
||||
LH = 0x21,
|
||||
LWL = 0x22,
|
||||
LW = 0x23,
|
||||
LBU = 0x24,
|
||||
LHU = 0x25,
|
||||
LWR = 0x26,
|
||||
SB = 0x28,
|
||||
SH = 0x29,
|
||||
SWL = 0x2A,
|
||||
SW = 0x2B,
|
||||
SWR = 0x2E,
|
||||
LWC2 = 0x32,
|
||||
SWC2 = 0x3A
|
||||
};
|
||||
enum Opcode {
|
||||
SPECIAL = 0x00,
|
||||
REGIMM = 0x01,
|
||||
J = 0x02,
|
||||
JAL = 0x03,
|
||||
BEQ = 0x04,
|
||||
BNE = 0x05,
|
||||
BLEZ = 0x06,
|
||||
BGTZ = 0x07,
|
||||
ADDI = 0x08,
|
||||
ADDIU = 0x09,
|
||||
SLTI = 0x0A,
|
||||
SLTIU = 0x0B,
|
||||
ANDI = 0x0C,
|
||||
ORI = 0x0D,
|
||||
XORI = 0x0E,
|
||||
LUI = 0x0F,
|
||||
COP0 = 0x10,
|
||||
COP2 = 0x12,
|
||||
LB = 0x20,
|
||||
LH = 0x21,
|
||||
LWL = 0x22,
|
||||
LW = 0x23,
|
||||
LBU = 0x24,
|
||||
LHU = 0x25,
|
||||
LWR = 0x26,
|
||||
SB = 0x28,
|
||||
SH = 0x29,
|
||||
SWL = 0x2A,
|
||||
SW = 0x2B,
|
||||
SWR = 0x2E,
|
||||
LWC2 = 0x32,
|
||||
SWC2 = 0x3A
|
||||
};
|
||||
|
||||
enum class SPECIALOpcode {
|
||||
SLL = 0x00,
|
||||
SRL = 0x02,
|
||||
SRA = 0x03,
|
||||
SLLV = 0x04,
|
||||
SRLV = 0x06,
|
||||
SRAV = 0x07,
|
||||
JR = 0x08,
|
||||
JALR = 0x09,
|
||||
SYSCALL = 0x0C,
|
||||
BREAK = 0x0D,
|
||||
MFHI = 0x10,
|
||||
MTHI = 0x11,
|
||||
MFLO = 0x12,
|
||||
MTLO = 0x13,
|
||||
MULT = 0x18,
|
||||
MULTU = 0x19,
|
||||
DIV = 0x1A,
|
||||
DIVU = 0x1B,
|
||||
ADD = 0x20,
|
||||
ADDU = 0x21,
|
||||
SUB = 0x22,
|
||||
SUBU = 0x23,
|
||||
AND = 0x24,
|
||||
OR = 0x25,
|
||||
XOR = 0x26,
|
||||
NOR = 0x27,
|
||||
SLT = 0x2A,
|
||||
SLTU = 0x2B
|
||||
};
|
||||
enum SPECIALOpcode {
|
||||
SLL = 0x00,
|
||||
SRL = 0x02,
|
||||
SRA = 0x03,
|
||||
SLLV = 0x04,
|
||||
SRLV = 0x06,
|
||||
SRAV = 0x07,
|
||||
JR = 0x08,
|
||||
JALR = 0x09,
|
||||
SYSCALL = 0x0C,
|
||||
BREAK = 0x0D,
|
||||
MFHI = 0x10,
|
||||
MTHI = 0x11,
|
||||
MFLO = 0x12,
|
||||
MTLO = 0x13,
|
||||
MULT = 0x18,
|
||||
MULTU = 0x19,
|
||||
DIV = 0x1A,
|
||||
DIVU = 0x1B,
|
||||
ADD = 0x20,
|
||||
ADDU = 0x21,
|
||||
SUB = 0x22,
|
||||
SUBU = 0x23,
|
||||
AND = 0x24,
|
||||
OR = 0x25,
|
||||
XOR = 0x26,
|
||||
NOR = 0x27,
|
||||
SLT = 0x2A,
|
||||
SLTU = 0x2B
|
||||
};
|
||||
|
||||
enum class REGIMMOpcode {
|
||||
BLTZ = 0x00,
|
||||
BGEZ = 0x01,
|
||||
BLTZAL = 0x10,
|
||||
BGEZAL = 0x11
|
||||
};
|
||||
enum REGIMMOpcode {
|
||||
BLTZ = 0x00,
|
||||
BGEZ = 0x01,
|
||||
BLTZAL = 0x10,
|
||||
BGEZAL = 0x11
|
||||
};
|
||||
|
||||
enum class COPOpcode {
|
||||
MF = 0x00,
|
||||
CF = 0x02,
|
||||
MT = 0x04,
|
||||
CT = 0x06,
|
||||
CO = 0x10
|
||||
};
|
||||
enum COPOpcode {
|
||||
MF = 0x00,
|
||||
CF = 0x02,
|
||||
MT = 0x04,
|
||||
CT = 0x06,
|
||||
CO = 0x10
|
||||
};
|
||||
|
||||
enum class COP0Opcode {
|
||||
RFE = 0x10
|
||||
};
|
||||
};
|
||||
enum COP0Opcode {
|
||||
RFE = 0x10
|
||||
};
|
||||
} // End namespace CpuOpcodes
|
|
@ -2,30 +2,30 @@
|
|||
|
||||
|
||||
void Disassembler::disassemble(CpuCore::Instruction instr, CpuCore* core) {
|
||||
switch ((CpuCore::Opcode)instr.primaryOpc.Value()) {
|
||||
case CpuCore::Opcode::SPECIAL: {
|
||||
switch ((CpuCore::SPECIALOpcode)instr.secondaryOpc.Value()) {
|
||||
case CpuCore::SPECIALOpcode::SLL: log("0x%08x: sll %s, %s, 0x%04x\n", core->pc, gprNames[instr.rd].c_str(), gprNames[instr.rt].c_str(), instr.shiftImm.Value()); break;
|
||||
case CpuCore::SPECIALOpcode::ADD: log("0x%08x: add %s, %s, %s\n", core->pc, gprNames[instr.rd].c_str(), gprNames[instr.rs].c_str(), gprNames[instr.rt].c_str()); break;
|
||||
case CpuCore::SPECIALOpcode::JR: log("0x%08x: jr %s\n", core->pc, gprNames[instr.rs].c_str()); break;
|
||||
case CpuCore::SPECIALOpcode::JALR: log("0x%08x: jalr %s\n", core->pc, gprNames[instr.rs].c_str()); break;
|
||||
case CpuCore::SPECIALOpcode::ADDU: log("0x%08x: addu %s, %s, %s\n", core->pc, gprNames[instr.rd].c_str(), gprNames[instr.rs].c_str(), gprNames[instr.rt].c_str()); break;
|
||||
case CpuCore::SPECIALOpcode::SLTU: log("0x%08x: sltu %s, %s, %s\n", core->pc, gprNames[instr.rd].c_str(), gprNames[instr.rs].c_str(), gprNames[instr.rt].c_str()); break;
|
||||
switch (instr.primaryOpc) {
|
||||
case CpuOpcodes::Opcode::SPECIAL: {
|
||||
switch (instr.secondaryOpc) {
|
||||
case CpuOpcodes::SPECIALOpcode::SLL: log("0x%08x: sll %s, %s, 0x%04x\n", core->pc, gprNames[instr.rd].c_str(), gprNames[instr.rt].c_str(), instr.shiftImm.Value()); break;
|
||||
case CpuOpcodes::SPECIALOpcode::ADD: log("0x%08x: add %s, %s, %s\n", core->pc, gprNames[instr.rd].c_str(), gprNames[instr.rs].c_str(), gprNames[instr.rt].c_str()); break;
|
||||
case CpuOpcodes::SPECIALOpcode::JR: log("0x%08x: jr %s\n", core->pc, gprNames[instr.rs].c_str()); break;
|
||||
case CpuOpcodes::SPECIALOpcode::JALR: log("0x%08x: jalr %s\n", core->pc, gprNames[instr.rs].c_str()); break;
|
||||
case CpuOpcodes::SPECIALOpcode::ADDU: log("0x%08x: addu %s, %s, %s\n", core->pc, gprNames[instr.rd].c_str(), gprNames[instr.rs].c_str(), gprNames[instr.rt].c_str()); break;
|
||||
case CpuOpcodes::SPECIALOpcode::SLTU: log("0x%08x: sltu %s, %s, %s\n", core->pc, gprNames[instr.rd].c_str(), gprNames[instr.rs].c_str(), gprNames[instr.rt].c_str()); break;
|
||||
default: log("0x%08x: (not disassembled secondary opc 0x%02x)\n", core->pc, instr.secondaryOpc.Value());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CpuCore::Opcode::J: log("0x%08x: j 0x%08x\n", core->pc, instr.jumpImm.Value()); break;
|
||||
case CpuCore::Opcode::JAL: log("0x%08x: jal 0x%08x\n", core->pc, instr.jumpImm.Value()); break;
|
||||
case CpuCore::Opcode::BNE: log("0x%08x: bne %s, %s, 0x%04x\n", core->pc, gprNames[instr.rs].c_str(), gprNames[instr.rt].c_str(), instr.imm.Value()); break;
|
||||
case CpuCore::Opcode::ADDI: log("0x%08x: addi %s, %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), gprNames[instr.rs].c_str(), instr.imm.Value()); break;
|
||||
case CpuCore::Opcode::ADDIU: log("0x%08x: addiu %s, %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), gprNames[instr.rs].c_str(), instr.imm.Value()); break;
|
||||
case CpuCore::Opcode::ANDI: log("0x%08x: andi %s, %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), gprNames[instr.rs].c_str(), instr.imm.Value()); break;
|
||||
case CpuCore::Opcode::ORI: log("0x%08x: ori %s, %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), gprNames[instr.rs].c_str(), instr.imm.Value()); break;
|
||||
case CpuCore::Opcode::LUI: log("0x%08x: lui %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), instr.imm.Value()); break;
|
||||
case CpuCore::Opcode::SB: log("0x%08x: sb %s, 0x%04x(%s) ; addr: 0x%08x\n", core->pc, gprNames[instr.rt].c_str(), instr.imm.Value(), gprNames[instr.rs].c_str(), core->gprs[instr.rs] + (u32)(s16)instr.imm); break;
|
||||
case CpuCore::Opcode::SH: log("0x%08x: sh %s, 0x%04x(%s) ; addr: 0x%08x\n", core->pc, gprNames[instr.rt].c_str(), instr.imm.Value(), gprNames[instr.rs].c_str(), core->gprs[instr.rs] + (u32)(s16)instr.imm); break;
|
||||
case CpuCore::Opcode::SW: log("0x%08x: sw %s, 0x%04x(%s) ; addr: 0x%08x\n", core->pc, gprNames[instr.rt].c_str(), instr.imm.Value(), gprNames[instr.rs].c_str(), core->gprs[instr.rs] + (u32)(s16)instr.imm); break;
|
||||
case CpuOpcodes::Opcode::J: log("0x%08x: j 0x%08x\n", core->pc, instr.jumpImm.Value()); break;
|
||||
case CpuOpcodes::Opcode::JAL: log("0x%08x: jal 0x%08x\n", core->pc, instr.jumpImm.Value()); break;
|
||||
case CpuOpcodes::Opcode::BNE: log("0x%08x: bne %s, %s, 0x%04x\n", core->pc, gprNames[instr.rs].c_str(), gprNames[instr.rt].c_str(), instr.imm.Value()); break;
|
||||
case CpuOpcodes::Opcode::ADDI: log("0x%08x: addi %s, %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), gprNames[instr.rs].c_str(), instr.imm.Value()); break;
|
||||
case CpuOpcodes::Opcode::ADDIU: log("0x%08x: addiu %s, %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), gprNames[instr.rs].c_str(), instr.imm.Value()); break;
|
||||
case CpuOpcodes::Opcode::ANDI: log("0x%08x: andi %s, %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), gprNames[instr.rs].c_str(), instr.imm.Value()); break;
|
||||
case CpuOpcodes::Opcode::ORI: log("0x%08x: ori %s, %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), gprNames[instr.rs].c_str(), instr.imm.Value()); break;
|
||||
case CpuOpcodes::Opcode::LUI: log("0x%08x: lui %s, 0x%04x\n", core->pc, gprNames[instr.rt].c_str(), instr.imm.Value()); break;
|
||||
case CpuOpcodes::Opcode::SB: log("0x%08x: sb %s, 0x%04x(%s) ; addr: 0x%08x\n", core->pc, gprNames[instr.rt].c_str(), instr.imm.Value(), gprNames[instr.rs].c_str(), core->gprs[instr.rs] + (u32)(s16)instr.imm); break;
|
||||
case CpuOpcodes::Opcode::SH: log("0x%08x: sh %s, 0x%04x(%s) ; addr: 0x%08x\n", core->pc, gprNames[instr.rt].c_str(), instr.imm.Value(), gprNames[instr.rs].c_str(), core->gprs[instr.rs] + (u32)(s16)instr.imm); break;
|
||||
case CpuOpcodes::Opcode::SW: log("0x%08x: sw %s, 0x%04x(%s) ; addr: 0x%08x\n", core->pc, gprNames[instr.rt].c_str(), instr.imm.Value(), gprNames[instr.rs].c_str(), core->gprs[instr.rs] + (u32)(s16)instr.imm); break;
|
||||
default: log("0x%08x: (not disassembled primary opc 0x%02x)\n", core->pc, instr.primaryOpc.Value());
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue