diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerAnalysis.cpp b/Source/Project64-rsp-core/Recompiler/RspRecompilerAnalysis.cpp index b5738c163..11bca729a 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerAnalysis.cpp +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerAnalysis.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -244,107 +245,6 @@ bool IsRegisterConstant(uint32_t Reg, uint32_t * Constant) } } -/* -IsOpcodeBranch -Output: -True: Opcode is a branch -False: Opcode is not a branch -Input: PC -*/ - -bool IsOpcodeBranch(uint32_t PC, RSPOpcode RspOp) -{ - PC = PC; // Unused - - switch (RspOp.op) - { - case RSP_REGIMM: - switch (RspOp.rt) - { - case RSP_REGIMM_BLTZ: - case RSP_REGIMM_BGEZ: - case RSP_REGIMM_BLTZAL: - case RSP_REGIMM_BGEZAL: - return true; - default: - //CompilerWarning(stdstr_f(stdstr_f("Unknown opcode in IsOpcodeBranch\n%s",RSPOpcodeName(RspOp.Hex,PC)).c_str()); - break; - } - break; - case RSP_SPECIAL: - switch (RspOp.funct) - { - case RSP_SPECIAL_SLL: - case RSP_SPECIAL_SRL: - case RSP_SPECIAL_SRA: - case RSP_SPECIAL_SLLV: - case RSP_SPECIAL_SRLV: - case RSP_SPECIAL_SRAV: - case RSP_SPECIAL_ADD: - case RSP_SPECIAL_ADDU: - case RSP_SPECIAL_SUB: - case RSP_SPECIAL_SUBU: - case RSP_SPECIAL_AND: - case RSP_SPECIAL_OR: - case RSP_SPECIAL_XOR: - case RSP_SPECIAL_NOR: - case RSP_SPECIAL_SLT: - case RSP_SPECIAL_SLTU: - case RSP_SPECIAL_BREAK: - break; - - case RSP_SPECIAL_JALR: - case RSP_SPECIAL_JR: - return true; - - default: - //CompilerWarning(stdstr_f("Unknown opcode in IsOpcodeBranch\n%s",RSPOpcodeName(RspOp.Hex,PC)).c_str()); - break; - } - break; - case RSP_J: - case RSP_JAL: - case RSP_BEQ: - case RSP_BNE: - case RSP_BLEZ: - case RSP_BGTZ: - return true; - - case RSP_ADDI: - case RSP_ADDIU: - case RSP_SLTI: - case RSP_SLTIU: - case RSP_ANDI: - case RSP_ORI: - case RSP_XORI: - case RSP_LUI: - - case RSP_CP0: - case RSP_CP2: - break; - - case RSP_LB: - case RSP_LH: - case RSP_LW: - case RSP_LBU: - case RSP_LHU: - case RSP_SB: - case RSP_SH: - case RSP_SW: - break; - - case RSP_LC2: - case RSP_SC2: - break; - - default: - //CompilerWarning(stdstr_f("Unknown opcode in IsOpcodeBranch\n%s",RSPOpcodeName(RspOp.Hex,PC)).c_str()); - break; - } - - return false; -} - /* GetInstructionInfo Output: None in regard to return value @@ -396,30 +296,30 @@ typedef struct #pragma warning(pop) -void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) +void GetInstructionInfo(uint32_t PC, const RSPOpcode & RspOp, OPCODE_INFO * info) { - switch (RspOp->op) + switch (RspOp.op) { case RSP_REGIMM: - switch (RspOp->rt) + switch (RspOp.rt) { case RSP_REGIMM_BLTZ: case RSP_REGIMM_BLTZAL: case RSP_REGIMM_BGEZ: case RSP_REGIMM_BGEZAL: info->flags = InvalidOpcode; - info->SourceReg0 = RspOp->rs; + info->SourceReg0 = RspOp.rs; info->SourceReg1 = UNUSED_OPERAND; break; default: - CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str()); + CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); info->flags = InvalidOpcode; break; } break; case RSP_SPECIAL: - switch (RspOp->funct) + switch (RspOp.funct) { case RSP_SPECIAL_BREAK: info->DestReg = UNUSED_OPERAND; @@ -431,8 +331,8 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_SPECIAL_SLL: case RSP_SPECIAL_SRL: case RSP_SPECIAL_SRA: - info->DestReg = RspOp->rd; - info->SourceReg0 = RspOp->rt; + info->DestReg = RspOp.rd; + info->SourceReg0 = RspOp.rt; info->SourceReg1 = UNUSED_OPERAND; info->flags = GPR_Instruction; break; @@ -449,9 +349,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_SPECIAL_NOR: case RSP_SPECIAL_SLT: case RSP_SPECIAL_SLTU: - info->DestReg = RspOp->rd; - info->SourceReg0 = RspOp->rs; - info->SourceReg1 = RspOp->rt; + info->DestReg = RspOp.rd; + info->SourceReg0 = RspOp.rs; + info->SourceReg1 = RspOp.rt; info->flags = GPR_Instruction; break; @@ -462,7 +362,7 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) break; default: - CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str()); + CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); info->flags = InvalidOpcode; break; } @@ -476,13 +376,13 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_BEQ: case RSP_BNE: info->flags = InvalidOpcode; - info->SourceReg0 = RspOp->rt; - info->SourceReg1 = RspOp->rs; + info->SourceReg0 = RspOp.rt; + info->SourceReg1 = RspOp.rs; break; case RSP_BLEZ: case RSP_BGTZ: info->flags = InvalidOpcode; - info->SourceReg0 = RspOp->rs; + info->SourceReg0 = RspOp.rs; info->SourceReg1 = UNUSED_OPERAND; break; @@ -493,27 +393,27 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_ANDI: case RSP_ORI: case RSP_XORI: - info->DestReg = RspOp->rt; - info->SourceReg0 = RspOp->rs; + info->DestReg = RspOp.rt; + info->SourceReg0 = RspOp.rs; info->SourceReg1 = UNUSED_OPERAND; info->flags = GPR_Instruction; break; case RSP_LUI: - info->DestReg = RspOp->rt; + info->DestReg = RspOp.rt; info->SourceReg0 = UNUSED_OPERAND; info->SourceReg1 = UNUSED_OPERAND; info->flags = GPR_Instruction; break; case RSP_CP0: - switch (RspOp->rs) + switch (RspOp.rs) { case RSP_COP0_MF: - info->DestReg = RspOp->rt; + info->DestReg = RspOp.rt; info->SourceReg0 = UNUSED_OPERAND; info->SourceReg1 = UNUSED_OPERAND; - if (RspOp->rd == 0x4 || RspOp->rd == 0x7) + if (RspOp.rd == 0x4 || RspOp.rd == 0x7) { info->flags = InvalidOpcode | COPO_MF_Instruction; } @@ -524,7 +424,7 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) break; case RSP_COP0_MT: - info->StoredReg = RspOp->rt; + info->StoredReg = RspOp.rt; info->SourceReg0 = UNUSED_OPERAND; info->SourceReg1 = UNUSED_OPERAND; info->flags = GPR_Instruction | Store_Operation; @@ -533,9 +433,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) break; case RSP_CP2: - if ((RspOp->rs & 0x10) != 0) + if ((RspOp.rs & 0x10) != 0) { - switch (RspOp->funct) + switch (RspOp.funct) { case RSP_VECTOR_VNOP: info->DestReg = UNUSED_OPERAND; @@ -557,9 +457,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_VECTOR_VNAND: case RSP_VECTOR_VNOR: case RSP_VECTOR_VNXOR: - info->DestReg = RspOp->sa; - info->SourceReg0 = RspOp->rd; - info->SourceReg1 = RspOp->rt; + info->DestReg = RspOp.sa; + info->SourceReg0 = RspOp.rd; + info->SourceReg1 = RspOp.rt; info->flags = VEC_Instruction | VEC_ResetAccum | Accum_Operation; break; case RSP_VECTOR_VMACF: @@ -568,9 +468,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_VECTOR_VMADM: case RSP_VECTOR_VMADN: case RSP_VECTOR_VMADH: - info->DestReg = RspOp->sa; - info->SourceReg0 = RspOp->rd; - info->SourceReg1 = RspOp->rt; + info->DestReg = RspOp.sa; + info->SourceReg0 = RspOp.rd; + info->SourceReg1 = RspOp.rt; info->flags = VEC_Instruction | VEC_Accumulate | Accum_Operation; break; case RSP_VECTOR_VADD: @@ -584,9 +484,9 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_VECTOR_VEQ: case RSP_VECTOR_VGE: case RSP_VECTOR_VNE: - info->DestReg = RspOp->sa; - info->SourceReg0 = RspOp->rd; - info->SourceReg1 = RspOp->rt; + info->DestReg = RspOp.sa; + info->SourceReg0 = RspOp.rd; + info->SourceReg1 = RspOp.rt; info->flags = VEC_Instruction | VEC_ResetAccum | Accum_Operation | Flag_Instruction; break; @@ -596,45 +496,45 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_VECTOR_VRCPH: case RSP_VECTOR_VRSQL: case RSP_VECTOR_VRSQH: - info->DestReg = RspOp->sa; - info->SourceReg0 = RspOp->rt; + info->DestReg = RspOp.sa; + info->SourceReg0 = RspOp.rt; info->SourceReg1 = UNUSED_OPERAND; info->flags = VEC_Instruction | VEC_ResetAccum | Accum_Operation; // Assume reset? break; case RSP_VECTOR_VMRG: - info->DestReg = RspOp->sa; - info->SourceReg0 = RspOp->rt; - info->SourceReg1 = RspOp->rd; + info->DestReg = RspOp.sa; + info->SourceReg0 = RspOp.rt; + info->SourceReg1 = RspOp.rd; info->flags = VEC_Instruction | VEC_ResetAccum | Accum_Operation | Flag_Instruction; // Assume reset? break; case RSP_VECTOR_VSAW: // info->flags = InvalidOpcode; - info->DestReg = RspOp->sa; + info->DestReg = RspOp.sa; info->SourceReg0 = UNUSED_OPERAND; info->SourceReg1 = UNUSED_OPERAND; info->flags = VEC_Instruction | Accum_Operation | VEC_Accumulate; break; default: - CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str()); + CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); info->flags = InvalidOpcode; break; } } else { - switch (RspOp->rs) + switch (RspOp.rs) { case RSP_COP2_CT: - info->StoredReg = RspOp->rt; + info->StoredReg = RspOp.rt; info->SourceReg0 = UNUSED_OPERAND; info->SourceReg1 = UNUSED_OPERAND; info->flags = GPR_Instruction | Store_Operation | Flag_Instruction; break; case RSP_COP2_CF: - info->DestReg = RspOp->rt; + info->DestReg = RspOp.rt; info->SourceReg0 = UNUSED_OPERAND; info->SourceReg1 = UNUSED_OPERAND; info->flags = GPR_Instruction | Load_Operation | Flag_Instruction; @@ -642,19 +542,19 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) // RD is always the vector register, RT is always GPR case RSP_COP2_MT: - info->DestReg = RspOp->rd; - info->SourceReg0 = RspOp->rt; + info->DestReg = RspOp.rd; + info->SourceReg0 = RspOp.rt; info->SourceReg1 = UNUSED_OPERAND; info->flags = VEC_Instruction | GPR_Instruction | Load_Operation; break; case RSP_COP2_MF: - info->DestReg = RspOp->rt; - info->SourceReg0 = RspOp->rd; + info->DestReg = RspOp.rt; + info->SourceReg0 = RspOp.rd; info->SourceReg1 = UNUSED_OPERAND; info->flags = VEC_Instruction | GPR_Instruction | Store_Operation; break; default: - CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str()); + CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); info->flags = InvalidOpcode; break; } @@ -665,21 +565,21 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_LW: case RSP_LBU: case RSP_LHU: - info->DestReg = RspOp->rt; - info->IndexReg = RspOp->base; + info->DestReg = RspOp.rt; + info->IndexReg = RspOp.base; info->SourceReg1 = UNUSED_OPERAND; info->flags = Load_Operation | GPR_Instruction; break; case RSP_SB: case RSP_SH: case RSP_SW: - info->StoredReg = RspOp->rt; - info->IndexReg = RspOp->base; + info->StoredReg = RspOp.rt; + info->IndexReg = RspOp.base; info->SourceReg1 = UNUSED_OPERAND; info->flags = Store_Operation | GPR_Instruction; break; case RSP_LC2: - switch (RspOp->rd) + switch (RspOp.rd) { case RSP_LSC2_BV: case RSP_LSC2_SV: @@ -689,8 +589,8 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_LSC2_LV: case RSP_LSC2_UV: case RSP_LSC2_PV: - info->DestReg = RspOp->rt; - info->IndexReg = RspOp->base; + info->DestReg = RspOp.rt; + info->IndexReg = RspOp.base; info->SourceReg1 = UNUSED_OPERAND; info->flags = Load_Operation | VEC_Instruction; break; @@ -699,13 +599,13 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) info->flags = InvalidOpcode; break; default: - CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str()); + CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); info->flags = InvalidOpcode; break; } break; case RSP_SC2: - switch (RspOp->rd) + switch (RspOp.rd) { case RSP_LSC2_BV: case RSP_LSC2_SV: @@ -718,8 +618,8 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) case RSP_LSC2_HV: case RSP_LSC2_FV: case RSP_LSC2_WV: - info->DestReg = RspOp->rt; - info->IndexReg = RspOp->base; + info->DestReg = RspOp.rt; + info->IndexReg = RspOp.base; info->SourceReg1 = UNUSED_OPERAND; info->flags = Store_Operation | VEC_Instruction; break; @@ -727,13 +627,13 @@ void GetInstructionInfo(uint32_t PC, RSPOpcode * RspOp, OPCODE_INFO * info) info->flags = InvalidOpcode; break; default: - CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp->Value).NameAndParam().c_str()).c_str()); + CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); info->flags = InvalidOpcode; break; } break; default: - /* CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s",RSPOpcodeName(RspOp->Hex,PC)).c_str()); + /* CompilerWarning(stdstr_f("Unknown opcode in GetInstructionInfo\n%s",RSPOpcodeName(RspOp.Hex,PC)).c_str()); */ info->flags = InvalidOpcode; break; @@ -764,8 +664,8 @@ bool DelaySlotAffectBranch(uint32_t PC) memset(&infoDelay, 0, sizeof(infoDelay)); memset(&infoBranch, 0, sizeof(infoBranch)); - GetInstructionInfo(PC, &BranchOp, &infoBranch); - GetInstructionInfo(DelayPC, &DelayOp, &infoDelay); + GetInstructionInfo(PC, BranchOp, &infoBranch); + GetInstructionInfo(DelayPC, DelayOp, &infoDelay); if ((infoDelay.flags & COPO_MF_Instruction) == COPO_MF_Instruction) { @@ -798,17 +698,19 @@ Input: Top, not the current operation, the one above Bottom: The current opcode for re-ordering bubble style */ -bool CompareInstructions(uint32_t PC, RSPOpcode * Top, RSPOpcode * Bottom) +bool CompareInstructions(uint32_t PC, const RSPInstruction & Top, RSPOpcode * Bottom) { OPCODE_INFO info0, info1; uint32_t InstructionType; - GetInstructionInfo(PC - 4, Top, &info0); - GetInstructionInfo(PC, Bottom, &info1); + RSPOpcode TopOpcode; + TopOpcode.Value = Top.Value(); + GetInstructionInfo(PC - 4, TopOpcode, &info0); + GetInstructionInfo(PC, *Bottom, &info1); #ifdef COMPARE_INSTRUCTIONS_VERBOSE - CPU_Message("Comparing %s (%X)", RSPOpcodeName(Top->Hex, PC - 4), PC - 4); - CPU_Message("to %s (%X)", RSPOpcodeName(Bottom->Hex, PC), PC); + CPU_Message("Comparing %s (%X)", Top.NameAndParam().c_str(), Top.Address()); + CPU_Message("to %s (%X)", RSPInstruction(PC, Bottom->Value).NameAndParam().c_str(), PC); #endif // Usually branches and such diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x86.cpp b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x86.cpp index 5f9d0841b..cc15d7176 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x86.cpp +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x86.cpp @@ -435,11 +435,10 @@ void CRSPRecompiler::ReOrderInstructions(uint32_t StartPC, uint32_t EndPC) { uint32_t InstructionCount = EndPC - StartPC; uint32_t Count, ReorderedOps, CurrentPC; - RSPOpcode PreviousOp, CurrentOp, RspOp; + RSPInstruction PreviousOp(StartPC, *(uint32_t *)(m_IMEM + (StartPC & 0xFFC))); + RSPOpcode CurrentOp, RspOp; - PreviousOp.Value = *(uint32_t *)(m_IMEM + (StartPC & 0xFFC)); - - if (IsOpcodeBranch(StartPC, PreviousOp)) + if (PreviousOp.IsBranch()) { // The sub block ends here anyway return; @@ -472,7 +471,7 @@ void CRSPRecompiler::ReOrderInstructions(uint32_t StartPC, uint32_t EndPC) for (Count = 0; Count < InstructionCount; Count += 4) { CurrentPC = StartPC; - PreviousOp.Value = *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC)); + PreviousOp = RSPInstruction(CurrentPC, *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC))); ReorderedOps = 0; for (;;) @@ -484,11 +483,11 @@ void CRSPRecompiler::ReOrderInstructions(uint32_t StartPC, uint32_t EndPC) } CurrentOp.Value = *(uint32_t *)(m_IMEM + CurrentPC); - if (CompareInstructions(CurrentPC, &PreviousOp, &CurrentOp)) + if (CompareInstructions(CurrentPC, PreviousOp, &CurrentOp)) { // Move current opcode up *(uint32_t *)(m_IMEM + CurrentPC - 4) = CurrentOp.Value; - *(uint32_t *)(m_IMEM + CurrentPC) = PreviousOp.Value; + *(uint32_t *)(m_IMEM + CurrentPC) = PreviousOp.Value(); ReorderedOps++; @@ -496,7 +495,7 @@ void CRSPRecompiler::ReOrderInstructions(uint32_t StartPC, uint32_t EndPC) CPU_Message("Swapped %X and %X", CurrentPC - 4, CurrentPC); #endif } - PreviousOp.Value = *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC)); + PreviousOp = RSPInstruction(CurrentPC, *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC))); if (IsOpcodeNop(CurrentPC) && IsOpcodeNop(CurrentPC + 4) && IsOpcodeNop(CurrentPC + 8)) { @@ -734,7 +733,7 @@ void CRSPRecompiler::BuildBranchLabels(void) { RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + i); - if (IsOpcodeBranch(i, RspOp)) + if (RSPInstruction(i, RspOp.Value).IsBranch()) { if (RspCode.LabelCount >= (sizeof(RspCode.BranchLabels) / sizeof(RspCode.BranchLabels[0])) - 1) { diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x86.h b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x86.h index 888b7a3c4..c80f2073a 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x86.h +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU-x86.h @@ -11,6 +11,7 @@ class CRSPSystem; class RSPRegisterHandlerPlugin; +class RSPInstruction; class CRSPRecompiler { @@ -74,8 +75,7 @@ extern bool ChangedPC; #define EntireAccum (Low16BitAccum | Middle16BitAccum | High16BitAccum) bool DelaySlotAffectBranch(uint32_t PC); -bool CompareInstructions(uint32_t PC, RSPOpcode * Top, RSPOpcode * Bottom); -bool IsOpcodeBranch(uint32_t PC, RSPOpcode RspOp); +bool CompareInstructions(uint32_t PC, const RSPInstruction & Top, RSPOpcode * Bottom); bool IsOpcodeNop(uint32_t PC); bool IsRegisterConstant(uint32_t Reg, uint32_t * Constant); diff --git a/Source/Project64-rsp-core/cpu/RSPInstruction.h b/Source/Project64-rsp-core/cpu/RSPInstruction.h index c2e86fcf5..abccf1580 100644 --- a/Source/Project64-rsp-core/cpu/RSPInstruction.h +++ b/Source/Project64-rsp-core/cpu/RSPInstruction.h @@ -7,27 +7,30 @@ class RSPInstruction { public: RSPInstruction(uint32_t Address, uint32_t Instruction); + RSPInstruction & operator=(const RSPInstruction &); - const char * Name(); - const char * Param(); - std::string NameAndParam(); + uint32_t Address() const; + bool IsBranch() const; + const char * Name() const; + const char * Param() const; + std::string NameAndParam() const; + uint32_t Value() const; private: RSPInstruction(void); RSPInstruction(const RSPInstruction &); - RSPInstruction & operator=(const RSPInstruction &); - void DecodeName(void); - void DecodeSpecialName(void); - void DecodeRegImmName(void); - void DecodeCop0Name(void); - void DecodeCop2Name(void); - void DecodeLSC2Name(const char LoadStoreIdent); + void DecodeName(void) const; + void DecodeSpecialName(void) const; + void DecodeRegImmName(void) const; + void DecodeCop0Name(void) const; + void DecodeCop2Name(void) const; + void DecodeLSC2Name(const char LoadStoreIdent) const; static const char * ElementSpecifier(uint32_t Element); uint32_t m_Address; RSPOpcode m_Instruction; - char m_Name[40]; - char m_Param[200]; + mutable char m_Name[40]; + mutable char m_Param[200]; }; \ No newline at end of file diff --git a/Source/Project64-rsp-core/cpu/RSPiInstruction.cpp b/Source/Project64-rsp-core/cpu/RSPiInstruction.cpp index b34e50501..e3342f3bd 100644 --- a/Source/Project64-rsp-core/cpu/RSPiInstruction.cpp +++ b/Source/Project64-rsp-core/cpu/RSPiInstruction.cpp @@ -1,6 +1,7 @@ #include "RSPInstruction.h" #include "RSPRegisters.h" #include +#include RSPInstruction::RSPInstruction(uint32_t Address, uint32_t Instruction) : m_Address(Address) @@ -10,7 +11,102 @@ RSPInstruction::RSPInstruction(uint32_t Address, uint32_t Instruction) : m_Instruction.Value = Instruction; } -const char * RSPInstruction::Name() +RSPInstruction & RSPInstruction::operator=(const RSPInstruction & e) +{ + m_Address = e.m_Address; + m_Instruction.Value = e.m_Instruction.Value; + memcpy(m_Name, e.m_Name, sizeof(m_Name)); + memcpy(m_Param, e.m_Param, sizeof(m_Param)); + return *this; +} + +uint32_t RSPInstruction::Address() const +{ + return m_Address; +} + +bool RSPInstruction::IsBranch() const +{ + switch (m_Instruction.op) + { + case RSP_REGIMM: + switch (m_Instruction.rt) + { + case RSP_REGIMM_BLTZ: + case RSP_REGIMM_BGEZ: + case RSP_REGIMM_BLTZAL: + case RSP_REGIMM_BGEZAL: + return true; + default: +#ifdef _DEBUG + g_Notify->BreakPoint(__FILE__, __LINE__); +#endif + break; + } + break; + case RSP_SPECIAL: + switch (m_Instruction.funct) + { + case RSP_SPECIAL_SLL: + case RSP_SPECIAL_SRL: + case RSP_SPECIAL_SRA: + case RSP_SPECIAL_SLLV: + case RSP_SPECIAL_SRLV: + case RSP_SPECIAL_SRAV: + case RSP_SPECIAL_ADD: + case RSP_SPECIAL_ADDU: + case RSP_SPECIAL_SUB: + case RSP_SPECIAL_SUBU: + case RSP_SPECIAL_AND: + case RSP_SPECIAL_OR: + case RSP_SPECIAL_XOR: + case RSP_SPECIAL_NOR: + case RSP_SPECIAL_SLT: + case RSP_SPECIAL_SLTU: + case RSP_SPECIAL_BREAK: + break; + case RSP_SPECIAL_JALR: + case RSP_SPECIAL_JR: + return true; + default: + break; + } + break; + case RSP_J: + case RSP_JAL: + case RSP_BEQ: + case RSP_BNE: + case RSP_BLEZ: + case RSP_BGTZ: + return true; + case RSP_ADDI: + case RSP_ADDIU: + case RSP_SLTI: + case RSP_SLTIU: + case RSP_ANDI: + case RSP_ORI: + case RSP_XORI: + case RSP_LUI: + case RSP_CP0: + case RSP_CP2: + case RSP_LB: + case RSP_LH: + case RSP_LW: + case RSP_LBU: + case RSP_LHU: + case RSP_SB: + case RSP_SH: + case RSP_SW: + case RSP_LC2: + case RSP_SC2: + break; + default: + break; + } + return false; +} + +const char * RSPInstruction::Name() const { if (m_Name[0] == '\0') { @@ -19,7 +115,7 @@ const char * RSPInstruction::Name() return m_Name; } -const char * RSPInstruction::Param() +const char * RSPInstruction::Param() const { if (m_Param[0] == '\0') { @@ -28,12 +124,17 @@ const char * RSPInstruction::Param() return m_Param; } -std::string RSPInstruction::NameAndParam() +std::string RSPInstruction::NameAndParam() const { return stdstr_f("%s %s", Name(), Param()); } -void RSPInstruction::DecodeName(void) +uint32_t RSPInstruction::Value() const +{ + return m_Instruction.Value; +} + +void RSPInstruction::DecodeName(void) const { switch (m_Instruction.op) { @@ -174,7 +275,7 @@ void RSPInstruction::DecodeName(void) } } -void RSPInstruction::DecodeSpecialName(void) +void RSPInstruction::DecodeSpecialName(void) const { switch (m_Instruction.funct) { @@ -266,7 +367,7 @@ void RSPInstruction::DecodeSpecialName(void) } } -void RSPInstruction::DecodeRegImmName(void) +void RSPInstruction::DecodeRegImmName(void) const { switch (m_Instruction.rt) { @@ -308,7 +409,7 @@ void RSPInstruction::DecodeRegImmName(void) } } -void RSPInstruction::DecodeCop0Name(void) +void RSPInstruction::DecodeCop0Name(void) const { switch (m_Instruction.rs) { @@ -326,7 +427,7 @@ void RSPInstruction::DecodeCop0Name(void) } } -void RSPInstruction::DecodeCop2Name(void) +void RSPInstruction::DecodeCop2Name(void) const { if ((m_Instruction.rs & 0x10) == 0) { @@ -620,7 +721,7 @@ void RSPInstruction::DecodeCop2Name(void) } } -void RSPInstruction::DecodeLSC2Name(const char LoadStoreIdent) +void RSPInstruction::DecodeLSC2Name(const char LoadStoreIdent) const { switch (m_Instruction.rd) {