project64/Source/Project64-rsp/cpu/RSPiInstruction.cpp

632 lines
28 KiB
C++

#include "RSPInstruction.h"
#include "../RSP Registers.h"
#include <Common/StdString.h>
RSPInstruction::RSPInstruction(uint32_t Address, uint32_t Instruction) :
m_Address(Address)
{
m_Name[0] = '\0';
m_Param[0] = '\0';
m_Instruction.Value = Instruction;
}
const char * RSPInstruction::Name()
{
if (m_Name[0] == '\0')
{
DecodeName();
}
return m_Name;
}
const char * RSPInstruction::Param()
{
if (m_Param[0] == '\0')
{
DecodeName();
}
return m_Param;
}
std::string RSPInstruction::NameAndParam()
{
return stdstr_f("%s %s", Name(), Param());
}
void RSPInstruction::DecodeName(void)
{
switch (m_Instruction.op)
{
case RSP_SPECIAL:
DecodeSpecialName();
break;
case RSP_REGIMM:
DecodeRegImmName();
break;
case RSP_J:
strcpy(m_Name, "J");
sprintf(m_Param, "0x%04X", (m_Instruction.target << 2) & 0x1FFC);
break;
case RSP_JAL:
strcpy(m_Name, "JAL");
sprintf(m_Param, "0x%04X", (m_Instruction.target << 2) & 0x1FFC);
break;
case RSP_BEQ:
if (m_Instruction.rs == 0 && m_Instruction.rt == 0)
{
strcpy(m_Name, "B");
sprintf(m_Param, "0x%08X", (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
}
else if (m_Instruction.rs == 0 || m_Instruction.rt == 0)
{
strcpy(m_Name, "BEQZ");
sprintf(m_Param, "%s, 0x%08X", GPR_Name(m_Instruction.rs == 0 ? m_Instruction.rt : m_Instruction.rs), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
}
else
{
strcpy(m_Name, "BEQ");
sprintf(m_Param, "%s, %s, 0x%08X", GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
}
break;
case RSP_BNE:
if ((m_Instruction.rs == 0) ^ (m_Instruction.rt == 0))
{
strcpy(m_Name, "BNEZ");
sprintf(m_Param, "%s, 0x%08X", GPR_Name(m_Instruction.rs == 0 ? m_Instruction.rt : m_Instruction.rs), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
}
else
{
strcpy(m_Name, "BNE");
sprintf(m_Param, "%s, %s, 0x%08X", GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
}
break;
case RSP_BLEZ:
strcpy(m_Name, "BLEZ");
sprintf(m_Param, "%s, 0x%08X", GPR_Name(m_Instruction.rs), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
break;
case RSP_BGTZ:
strcpy(m_Name, "BGTZ");
sprintf(m_Param, "%s, 0x%08X", GPR_Name(m_Instruction.rs), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
break;
case RSP_ADDI:
strcpy(m_Name, "ADDI");
sprintf(m_Param, "%s, %s, 0x%04X", GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs), m_Instruction.immediate);
break;
case RSP_ADDIU:
strcpy(m_Name, "ADDIU");
sprintf(m_Param, "%s, %s, 0x%04X", GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs), m_Instruction.immediate);
break;
case RSP_SLTI:
strcpy(m_Name, "SLTI");
sprintf(m_Param, "%s, %s, 0x%04X", GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs), m_Instruction.immediate);
break;
case RSP_SLTIU:
strcpy(m_Name, "SLTIU");
sprintf(m_Param, "%s, %s, 0x%04X", GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs), m_Instruction.immediate);
break;
case RSP_ANDI:
strcpy(m_Name, "ANDI");
sprintf(m_Param, "%s, %s, 0x%04X", GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs), m_Instruction.immediate);
break;
case RSP_ORI:
strcpy(m_Name, "ORI");
sprintf(m_Param, "%s, %s, 0x%04X", GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs), m_Instruction.immediate);
break;
case RSP_XORI:
strcpy(m_Name, "XORI");
sprintf(m_Param, "%s, %s, 0x%04X", GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs), m_Instruction.immediate);
break;
case RSP_LUI:
strcpy(m_Name, "LUI");
sprintf(m_Param, "%s, 0x%04X", GPR_Name(m_Instruction.rt), m_Instruction.immediate);
break;
case RSP_CP0:
DecodeCop0Name();
break;
case RSP_CP2:
DecodeCop2Name();
break;
case RSP_LB:
strcpy(m_Name, "LB");
sprintf(m_Param, "%s, 0x%04X (%s)", GPR_Name(m_Instruction.rt), m_Instruction.offset, GPR_Name(m_Instruction.base));
break;
case RSP_LH:
strcpy(m_Name, "LH");
sprintf(m_Param, "%s, 0x%04X (%s)", GPR_Name(m_Instruction.rt), m_Instruction.offset, GPR_Name(m_Instruction.base));
break;
case RSP_LW:
strcpy(m_Name, "LW");
sprintf(m_Param, "%s, 0x%04X (%s)", GPR_Name(m_Instruction.rt), m_Instruction.offset, GPR_Name(m_Instruction.base));
break;
case RSP_LBU:
strcpy(m_Name, "LBU");
sprintf(m_Param, "%s, 0x%04X (%s)", GPR_Name(m_Instruction.rt), m_Instruction.offset, GPR_Name(m_Instruction.base));
break;
case RSP_LHU:
strcpy(m_Name, "LHU");
sprintf(m_Param, "%s, 0x%04X (%s)", GPR_Name(m_Instruction.rt), m_Instruction.offset, GPR_Name(m_Instruction.base));
break;
case RSP_SB:
strcpy(m_Name, "SB");
sprintf(m_Param, "%s, 0x%04X (%s)", GPR_Name(m_Instruction.rt), m_Instruction.offset, GPR_Name(m_Instruction.base));
break;
case RSP_SH:
strcpy(m_Name, "SH");
sprintf(m_Param, "%s, 0x%04X (%s)", GPR_Name(m_Instruction.rt), m_Instruction.offset, GPR_Name(m_Instruction.base));
break;
case RSP_SW:
strcpy(m_Name, "SW");
sprintf(m_Param, "%s, 0x%04X (%s)", GPR_Name(m_Instruction.rt), m_Instruction.offset, GPR_Name(m_Instruction.base));
break;
case RSP_LC2:
DecodeLC2Name();
break;
case RSP_SC2:
DecodeSC2Name();
break;
default:
strcpy(m_Name, "UNKNOWN");
sprintf(m_Param, "0x%08X", m_Instruction.Value);
}
}
void RSPInstruction::DecodeSpecialName(void)
{
switch (m_Instruction.funct)
{
case RSP_SPECIAL_SLL:
if (m_Instruction.Value != 0)
{
strcpy(m_Name, "SLL");
sprintf(m_Param, "%s, %s, 0x%X", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rt), m_Instruction.sa);
}
else
{
strcpy(m_Name, "NOP");
}
break;
case RSP_SPECIAL_SRL:
strcpy(m_Name, "SRL");
sprintf(m_Param, "%s, %s, 0x%X", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rt), m_Instruction.sa);
break;
case RSP_SPECIAL_SRA:
strcpy(m_Name, "SRA");
sprintf(m_Param, "%s, %s, 0x%X", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rt), m_Instruction.sa);
break;
case RSP_SPECIAL_SLLV:
strcpy(m_Name, "SLLV");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd),GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs));
break;
case RSP_SPECIAL_SRLV:
strcpy(m_Name, "SRLV");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs));
break;
case RSP_SPECIAL_SRAV:
strcpy(m_Name, "SRAV");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rt), GPR_Name(m_Instruction.rs));
break;
case RSP_SPECIAL_JR:
strcpy(m_Name, "JR");
sprintf(m_Param, "%s", GPR_Name(m_Instruction.rs));
break;
case RSP_SPECIAL_JALR:
strcpy(m_Name, "JALR");
sprintf(m_Param, "%s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs));
break;
case RSP_SPECIAL_BREAK:
strcpy(m_Name, "BREAK");
break;
case RSP_SPECIAL_ADD:
strcpy(m_Name, "ADD");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
case RSP_SPECIAL_ADDU:
strcpy(m_Name, "ADDU");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
case RSP_SPECIAL_SUB:
strcpy(m_Name, "SUB");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
case RSP_SPECIAL_SUBU:
strcpy(m_Name, "SUBU");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
case RSP_SPECIAL_AND:
strcpy(m_Name, "AND");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
case RSP_SPECIAL_OR:
strcpy(m_Name, "OR");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
case RSP_SPECIAL_XOR:
strcpy(m_Name, "XOR");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
case RSP_SPECIAL_NOR:
strcpy(m_Name, "NOR");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
case RSP_SPECIAL_SLT:
strcpy(m_Name, "SLT");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
case RSP_SPECIAL_SLTU:
strcpy(m_Name, "SLTU");
sprintf(m_Param, "%s, %s, %s", GPR_Name(m_Instruction.rd), GPR_Name(m_Instruction.rs), GPR_Name(m_Instruction.rt));
break;
default:
strcpy(m_Name, "UNKNOWN");
sprintf(m_Param, "0x%08X", m_Instruction.Value);
}
}
void RSPInstruction::DecodeRegImmName(void)
{
switch (m_Instruction.rt)
{
case RSP_REGIMM_BLTZ:
strcpy(m_Name, "BLTZ");
sprintf(m_Param, "%s, 0x%04X", GPR_Name(m_Instruction.rs), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
break;
case RSP_REGIMM_BGEZ:
if (m_Instruction.rs == 0)
{
strcpy(m_Name, "B");
sprintf(m_Param, "0x%04X", (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
}
else
{
strcpy(m_Name, "BGEZ");
sprintf(m_Param, "%s, 0x%04X", GPR_Name(m_Instruction.rs), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
}
break;
case RSP_REGIMM_BLTZAL:
strcpy(m_Name, "BLTZAL");
sprintf(m_Param, "%s, 0x%04X", GPR_Name(m_Instruction.rs), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
break;
case RSP_REGIMM_BGEZAL:
if (m_Instruction.rs == 0)
{
strcpy(m_Name, "BAL");
sprintf(m_Param, "0x%04X", (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
}
else
{
strcpy(m_Name, "BGEZAL");
sprintf(m_Param, "%s, 0x%04X", GPR_Name(m_Instruction.rs), (m_Address + ((short)m_Instruction.offset << 2) + 4) & 0x1FFC);
}
break;
default:
strcpy(m_Name, "UNKNOWN");
sprintf(m_Param, "0x%08X", m_Instruction.Value);
}
}
void RSPInstruction::DecodeCop0Name(void)
{
switch (m_Instruction.rs)
{
case RSP_COP0_MF:
strcpy(m_Name, "MFC0");
sprintf(m_Param, "%s, %s", GPR_Name(m_Instruction.rt), COP0_Name(m_Instruction.rd));
break;
case RSP_COP0_MT:
strcpy(m_Name, "MTC0");
sprintf(m_Param, "%s, %s", GPR_Name(m_Instruction.rt), COP0_Name(m_Instruction.rd));
break;
default:
strcpy(m_Name, "UNKNOWN");
sprintf(m_Param, "0x%08X", m_Instruction.Value);
}
}
void RSPInstruction::DecodeCop2Name(void)
{
if ((m_Instruction.rs & 0x10) == 0)
{
switch (m_Instruction.rs)
{
case RSP_COP2_MF:
strcpy(m_Name, "MFC2");
sprintf(m_Param, "%s, $v%d[%d]", GPR_Name(m_Instruction.rt), m_Instruction.rd, m_Instruction.sa >> 1);
break;
case RSP_COP2_CF:
strcpy(m_Name, "CFC2");
sprintf(m_Param, "%s, %d", GPR_Name(m_Instruction.rt), m_Instruction.rd % 4);
break;
case RSP_COP2_MT:
strcpy(m_Name, "MTC2");
sprintf(m_Param, "%s, $v%d[%d]", GPR_Name(m_Instruction.rt), m_Instruction.rd, m_Instruction.sa >> 1);
break;
case RSP_COP2_CT:
strcpy(m_Name, "CTC2");
sprintf(m_Param, "%s, %d", GPR_Name(m_Instruction.rt), m_Instruction.rd % 4);
break;
default:
strcpy(m_Name, "UNKNOWN");
sprintf(m_Param, "0x%08X", m_Instruction.Value);
}
}
else
{
switch (m_Instruction.funct)
{
case RSP_VECTOR_VMULF:
strcpy(m_Name, "VMULF");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMULU:
strcpy(m_Name, "VMULU");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMUDL:
strcpy(m_Name, "VMUDL");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMUDM:
strcpy(m_Name, "VMUDM");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMUDN:
strcpy(m_Name, "VMUDN");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMUDH:
strcpy(m_Name, "VMUDH");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMACF:
strcpy(m_Name, "VMACF");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMACU:
strcpy(m_Name, "VMACU");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMACQ:
strcpy(m_Name, "VMACQ");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMADL:
strcpy(m_Name, "VMADL");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMADM:
strcpy(m_Name, "VMADM");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMADN:
strcpy(m_Name, "VMADN");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMADH:
strcpy(m_Name, "VMADH");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VADD:
strcpy(m_Name, "VADD");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VSUB:
strcpy(m_Name, "VSUB");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VABS:
strcpy(m_Name, "VABS");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VADDC:
strcpy(m_Name, "VADDC");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VSUBC:
strcpy(m_Name, "VSUBC");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VSAW:
strcpy(m_Name, "VSAW");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VLT:
strcpy(m_Name, "VLT");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VEQ:
strcpy(m_Name, "VEQ");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VNE:
strcpy(m_Name, "VNE");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VGE:
strcpy(m_Name, "VGE");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VCL:
strcpy(m_Name, "VCL");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VCH:
strcpy(m_Name, "VCH");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VCR:
strcpy(m_Name, "VCR");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VMRG:
strcpy(m_Name, "VMRG");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VAND:
strcpy(m_Name, "VAND");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VNAND:
strcpy(m_Name, "VNAND");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VOR:
strcpy(m_Name, "VOR");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VNOR:
strcpy(m_Name, "VNOR");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VXOR:
strcpy(m_Name, "VXOR");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VNXOR:
strcpy(m_Name, "VNXOR");
sprintf(m_Param, "$v%d, $v%d, $v%d%s", m_Instruction.sa, m_Instruction.rd, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF));
break;
case RSP_VECTOR_VRCP:
strcpy(m_Name, "VRCP");
sprintf(m_Param, "$v%d[%d], $v%d%s", m_Instruction.sa, m_Instruction.rd & 0x7, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF)); break;
case RSP_VECTOR_VRCPL:
strcpy(m_Name, "VRCPL");
sprintf(m_Param, "$v%d[%d], $v%d%s", m_Instruction.sa, m_Instruction.rd & 0x7, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF)); break;
break;
case RSP_VECTOR_VRCPH:
strcpy(m_Name, "VRCPH");
sprintf(m_Param, "$v%d[%d], $v%d%s", m_Instruction.sa, m_Instruction.rd & 0x7, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF)); break;
break;
case RSP_VECTOR_VMOV:
strcpy(m_Name, "VMOV");
sprintf(m_Param, "$v%d[%d], $v%d%s", m_Instruction.sa, m_Instruction.rd & 0x7, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF)); break;
break;
case RSP_VECTOR_VRSQ:
strcpy(m_Name, "VRSQ");
sprintf(m_Param, "$v%d[%d], $v%d%s", m_Instruction.sa, m_Instruction.rd & 0x7, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF)); break;
break;
case RSP_VECTOR_VRSQL:
strcpy(m_Name, "VRSQL");
sprintf(m_Param, "$v%d[%d], $v%d%s", m_Instruction.sa, m_Instruction.rd & 0x7, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF)); break;
break;
case RSP_VECTOR_VRSQH:
strcpy(m_Name, "VRSQH");
sprintf(m_Param, "$v%d[%d], $v%d%s", m_Instruction.sa, m_Instruction.rd & 0x7, m_Instruction.rt, ElementSpecifier(m_Instruction.rs & 0xF)); break;
break;
case RSP_VECTOR_VNOP:
strcpy(m_Name, "VNOP");
strcpy(m_Param, "");
break;
default:
strcpy(m_Name, "UNKNOWN");
sprintf(m_Param, "0x%08X", m_Instruction.Value);
}
}
}
void RSPInstruction::DecodeLC2Name(void)
{
switch (m_Instruction.rd)
{
case RSP_LSC2_BV:
strcpy(m_Name, "LBV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_SV:
strcpy(m_Name, "LSV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_LV:
strcpy(m_Name, "LLV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_DV:
strcpy(m_Name, "LDV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_QV:
strcpy(m_Name, "LQV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_RV:
strcpy(m_Name, "LRV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_PV:
strcpy(m_Name, "LPV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_UV:
strcpy(m_Name, "LUV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_HV:
strcpy(m_Name, "LHV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_FV:
strcpy(m_Name, "LFV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_TV:
strcpy(m_Name, "LTV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
default:
strcpy(m_Name, "UNKNOWN");
sprintf(m_Param, "0x%08X", m_Instruction.Value);
}
}
void RSPInstruction::DecodeSC2Name(void)
{
switch (m_Instruction.rd)
{
case RSP_LSC2_BV:
strcpy(m_Name, "SBV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_SV:
strcpy(m_Name, "SSV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_LV:
strcpy(m_Name, "SLV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_DV:
strcpy(m_Name, "SDV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_QV:
strcpy(m_Name, "SQV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_RV:
strcpy(m_Name, "SRV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_PV:
strcpy(m_Name, "SPV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_UV:
strcpy(m_Name, "SUV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_HV:
strcpy(m_Name, "SHV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_FV:
strcpy(m_Name, "SFV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
case RSP_LSC2_TV:
strcpy(m_Name, "STV");
sprintf(m_Param, "$v%d[%d], %c0x%03X(%s)", m_Instruction.rt, m_Instruction.del, (m_Instruction.voffset < 0) ? '-' : '+', abs(m_Instruction.voffset), GPR_Name(m_Instruction.base));
break;
default:
strcpy(m_Name, "UNKNOWN");
sprintf(m_Param, "0x%08X", m_Instruction.Value);
}
}