[CPU] Fix UB

This commit is contained in:
liuk7071 2023-07-25 17:15:08 +02:00
parent 6b6867262a
commit 366a9fa418
3 changed files with 183 additions and 181 deletions

View file

@ -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) {

View file

@ -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

View file

@ -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());
}
}