diff --git a/Source/Project64-rsp-core/Project64-rsp-core.vcxproj b/Source/Project64-rsp-core/Project64-rsp-core.vcxproj index a5912aa53..95a1217f8 100644 --- a/Source/Project64-rsp-core/Project64-rsp-core.vcxproj +++ b/Source/Project64-rsp-core/Project64-rsp-core.vcxproj @@ -43,7 +43,6 @@ - @@ -79,11 +78,11 @@ - + diff --git a/Source/Project64-rsp-core/Project64-rsp-core.vcxproj.filters b/Source/Project64-rsp-core/Project64-rsp-core.vcxproj.filters index d49022cdb..8c3fe2950 100644 --- a/Source/Project64-rsp-core/Project64-rsp-core.vcxproj.filters +++ b/Source/Project64-rsp-core/Project64-rsp-core.vcxproj.filters @@ -48,9 +48,6 @@ Source Files\cpu - - Source Files\cpu - Source Files\cpu @@ -155,9 +152,6 @@ Header Files\cpu - - Header Files\cpu - Header Files\cpu @@ -224,5 +218,8 @@ Header Files\cpu + + Header Files\cpu + \ No newline at end of file diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerAnalysis.cpp b/Source/Project64-rsp-core/Recompiler/RspRecompilerAnalysis.cpp index e3f5cac0a..d32f87a1d 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerAnalysis.cpp +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerAnalysis.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -29,1093 +28,6 @@ bool IsOpcodeNop(uint32_t PC) return false; } -/* -IsNextInstructionMmx -Output: Determines EMMS status -Input: PC -*/ - -bool IsNextInstructionMmx(uint32_t PC) -{ - RSPOpcode RspOp; - - if (!IsMmxEnabled) - return false; - - PC += 4; - if (PC >= 0x1000) return false; - RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + (PC & 0xFFC)); - - if (RspOp.op != RSP_CP2) - return false; - - if ((RspOp.rs & 0x10) != 0) - { - switch (RspOp.funct) - { - case RSP_VECTOR_VMULF: - case RSP_VECTOR_VMUDL: // Warning: Not all handled? - case RSP_VECTOR_VMUDM: - case RSP_VECTOR_VMUDN: - case RSP_VECTOR_VMUDH: - if (true == WriteToAccum(7, PC)) - { - return false; - } - else if ((RspOp.rs & 0x0f) >= 2 && (RspOp.rs & 0x0f) <= 7 && IsMmx2Enabled == false) - { - return false; - } - else - return true; - - case RSP_VECTOR_VABS: - case RSP_VECTOR_VAND: - case RSP_VECTOR_VOR: - case RSP_VECTOR_VXOR: - case RSP_VECTOR_VNAND: - case RSP_VECTOR_VNOR: - case RSP_VECTOR_VNXOR: - if (true == WriteToAccum(Low16BitAccum, PC)) - { - return false; - } - else if ((RspOp.rs & 0x0f) >= 2 && (RspOp.rs & 0x0f) <= 7 && IsMmx2Enabled == false) - { - return false; - } - else - return true; - - case RSP_VECTOR_VADD: - case RSP_VECTOR_VSUB: - // Requires no accumulator write, and no flags! - if (WriteToAccum(Low16BitAccum, PC) == true) - { - return false; - } - else if (UseRspFlags(PC) == true) - { - return false; - } - else if ((RspOp.rs & 0x0f) >= 2 && (RspOp.rs & 0x0f) <= 7 && IsMmx2Enabled == false) - { - return false; - } - else - return true; - - default: - return false; - } - } - else - return false; -} - -/* -WriteToAccum2 -Output: -True: Accumulation series -False: Accumulator is reset after this op -Input: PC, location in accumulator -*/ - -#define HIT_BRANCH 0x2 - -uint32_t WriteToAccum2(int Location, int PC, bool RecursiveCall) -{ - RSPOpcode RspOp; - uint32_t BranchTarget = 0; - signed int BranchImmed = 0; - int Instruction_State = NextInstruction; - - if (Compiler.bAccum == false) return true; - - if (Instruction_State == RSPPIPELINE_DELAY_SLOT) - { - return true; - } - - do - { - PC += 4; - if (PC >= 0x1000) - { - return true; - } - RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + (PC & 0xFFC)); - - 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: - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - 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: - return true; - - case RSP_SPECIAL_JR: - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - break; - case RSP_J: - // There is no way a loopback is going to use accumulator - if (Compiler.bAudioUcode && (((int)(RspOp.target << 2) & 0xFFC) < PC)) - { - return false; - } - // Rarely occurs, so we let them have their way - else - { - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - } - - case RSP_JAL: - // There is no way calling a subroutine is going to use an accumulator - // or come back and continue an existing calculation - if (Compiler.bAudioUcode) - { - break; - } - else - { - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - } - - case RSP_BEQ: - case RSP_BNE: - case RSP_BLEZ: - case RSP_BGTZ: - BranchImmed = (short)RspOp.offset; - if (Compiler.bAudioUcode) - { - RSPOpcode NextOp; - - // Ignore backward branches and pretend it's a NOP - if (BranchImmed <= 0) - { - break; - } - // If the opcode (which is 8 bytes before the destination and also a J backward) then ignore this - BranchImmed = (PC + ((short)RspOp.offset << 2) + 4) & 0xFFC; - NextOp.Value = *(uint32_t *)(RSPInfo.IMEM + ((BranchImmed - 8) & 0xFFC)); - - if (RspOp.op == RSP_J && (int)(RspOp.target << 2) < PC) - { - break; - } - } - BranchTarget = (PC + ((short)RspOp.offset << 2) + 4) & 0xFFC; - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - 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: - break; - - case RSP_CP2: - if ((RspOp.rs & 0x10) != 0) - { - switch (RspOp.funct) - { - case RSP_VECTOR_VMULF: - case RSP_VECTOR_VMULU: - case RSP_VECTOR_VMUDL: - case RSP_VECTOR_VMUDM: - case RSP_VECTOR_VMUDN: - case RSP_VECTOR_VMUDH: - return false; - case RSP_VECTOR_VMACF: - case RSP_VECTOR_VMACU: - case RSP_VECTOR_VMADL: - case RSP_VECTOR_VMADM: - case RSP_VECTOR_VMADN: - return true; - case RSP_VECTOR_VMADH: - if (Location == Low16BitAccum) - { - break; - } - return true; - - case RSP_VECTOR_VABS: - case RSP_VECTOR_VADD: - case RSP_VECTOR_VADDC: - case RSP_VECTOR_VSUB: - case RSP_VECTOR_VSUBC: - case RSP_VECTOR_VAND: - case RSP_VECTOR_VNAND: - case RSP_VECTOR_VOR: - case RSP_VECTOR_VNOR: - case RSP_VECTOR_VXOR: - case RSP_VECTOR_VNXOR: - // Since these modify the accumulator lower-16 bits we can - // safely assume these 'reset' the accumulator no matter what - // return false; - case RSP_VECTOR_VCR: - case RSP_VECTOR_VCH: - case RSP_VECTOR_VCL: - case RSP_VECTOR_VRCP: - case RSP_VECTOR_VRCPL: - case RSP_VECTOR_VRCPH: - case RSP_VECTOR_VRSQL: - case RSP_VECTOR_VRSQH: - case RSP_VECTOR_VLT: - case RSP_VECTOR_VEQ: - case RSP_VECTOR_VGE: - case RSP_VECTOR_VNE: - case RSP_VECTOR_VMRG: - case RSP_VECTOR_VMOV: - if (Location == Low16BitAccum) - { - return false; - } - break; - - case RSP_VECTOR_VSAW: - return true; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - } - else - { - switch (RspOp.rs) - { - case RSP_COP2_CF: - case RSP_COP2_CT: - case RSP_COP2_MT: - case RSP_COP2_MF: - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - } - 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: - switch (RspOp.rd) - { - case RSP_LSC2_BV: - case RSP_LSC2_SV: - case RSP_LSC2_DV: - case RSP_LSC2_RV: - case RSP_LSC2_QV: - case RSP_LSC2_LV: - case RSP_LSC2_UV: - case RSP_LSC2_PV: - case RSP_LSC2_TV: - case RSP_LSC2_HV: - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - break; - case RSP_SC2: - switch (RspOp.rd) - { - case RSP_LSC2_BV: - case RSP_LSC2_SV: - case RSP_LSC2_LV: - case RSP_LSC2_DV: - case RSP_LSC2_QV: - case RSP_LSC2_RV: - case RSP_LSC2_PV: - case RSP_LSC2_UV: - case RSP_LSC2_HV: - case RSP_LSC2_FV: - case RSP_LSC2_WV: - case RSP_LSC2_TV: - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - switch (Instruction_State) - { - case RSPPIPELINE_NORMAL: break; - case RSPPIPELINE_DO_DELAY_SLOT: - Instruction_State = RSPPIPELINE_DELAY_SLOT; - break; - case RSPPIPELINE_DELAY_SLOT: - Instruction_State = RSPPIPELINE_FINISH_BLOCK; - break; - } - } while (Instruction_State != RSPPIPELINE_FINISH_BLOCK); - - /* - This is a tricky situation because most of the - microcode does loops, so looping back and checking - can prove effective, but it's still a branch... - */ - - if (BranchTarget != 0 && RecursiveCall == false) - { - uint32_t BranchTaken, BranchFall; - - // Analysis of branch taken - BranchTaken = WriteToAccum2(Location, BranchTarget - 4, true); - // Analysis of branch as NOP - BranchFall = WriteToAccum2(Location, PC, true); - - if (BranchImmed < 0) - { - if (BranchTaken != false) - { - - // Took this back branch and found a place - // that needs this vector as a source - - return true; - } - else if (BranchFall == HIT_BRANCH) - { - return true; - } - // Otherwise this is completely valid - return BranchFall; - } - else - { - if (BranchFall != false) - { - - // Took this forward branch and found a place - // that needs this vector as a source - - return true; - } - else if (BranchTaken == HIT_BRANCH) - { - return true; - } - // Otherwise this is completely valid - return BranchTaken; - } - } - return true; -} - -bool WriteToAccum(int Location, int PC) -{ - uint32_t value = WriteToAccum2(Location, PC, false); - - if (value == HIT_BRANCH) - { - return true; /* ??? */ - } - else - return value != 0; -} - -/* -WriteToVectorDest -Output: -True: Destination is used as a source later -False: Destination is overwritten later -Input: PC, Register -*/ - -bool WriteToVectorDest2(uint32_t DestReg, int PC, bool RecursiveCall) -{ - RSPOpcode RspOp; - uint32_t BranchTarget = 0; - signed int BranchImmed = 0; - - int Instruction_State = NextInstruction; - - if (Compiler.bDest == false) return true; - - if (Instruction_State == RSPPIPELINE_DELAY_SLOT) - { - return true; - } - - do - { - PC += 4; - if (PC >= 0x1000) - { - return true; - } - RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + (PC & 0xFFC)); - - 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: - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - 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: - return true; - - case RSP_SPECIAL_JR: - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - break; - case RSP_J: - // There is no way a loopback is going to use accumulator - if (Compiler.bAudioUcode && (int)(RspOp.target << 2) < PC) - { - return false; - } - // Rarely occurs, so we let them have their way - return true; - - case RSP_JAL: - // Assume register is being passed to function or used after the function call - return true; - - case RSP_BEQ: - case RSP_BNE: - case RSP_BLEZ: - case RSP_BGTZ: - BranchImmed = (short)RspOp.offset; - if (Compiler.bAudioUcode) - { - RSPOpcode NextOp; - - // Ignore backward branches and pretend it's a NOP - if (BranchImmed <= 0) - { - break; - } - // If the opcode (which is 8 bytes before the destination and also a J backward) then ignore this - BranchImmed = (PC + ((short)RspOp.offset << 2) + 4) & 0xFFC; - RSP_LW_IMEM(BranchImmed - 8, &NextOp.Value); - if (RspOp.op == RSP_J && (int)(RspOp.target << 2) < PC) - { - break; - } - } - BranchTarget = (PC + ((short)RspOp.offset << 2) + 4) & 0xFFC; - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - 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: - break; - - case RSP_CP2: - if ((RspOp.rs & 0x10) != 0) - { - switch (RspOp.funct) - { - case RSP_VECTOR_VMULF: - case RSP_VECTOR_VMULU: - case RSP_VECTOR_VMUDL: - case RSP_VECTOR_VMUDM: - case RSP_VECTOR_VMUDN: - case RSP_VECTOR_VMUDH: - case RSP_VECTOR_VMACF: - case RSP_VECTOR_VMACU: - case RSP_VECTOR_VMADL: - case RSP_VECTOR_VMADM: - case RSP_VECTOR_VMADN: - case RSP_VECTOR_VMADH: - case RSP_VECTOR_VADD: - case RSP_VECTOR_VADDC: - case RSP_VECTOR_VSUB: - case RSP_VECTOR_VSUBC: - case RSP_VECTOR_VAND: - case RSP_VECTOR_VNAND: - case RSP_VECTOR_VOR: - case RSP_VECTOR_VNOR: - case RSP_VECTOR_VXOR: - case RSP_VECTOR_VNXOR: - case RSP_VECTOR_VABS: - if (DestReg == RspOp.rd) - { - return true; - } - if (DestReg == RspOp.rt) - { - return true; - } - if (DestReg == RspOp.sa) - { - return false; - } - break; - - case RSP_VECTOR_VMOV: - case RSP_VECTOR_VRCP: - case RSP_VECTOR_VRCPL: - case RSP_VECTOR_VRCPH: - case RSP_VECTOR_VRSQL: - case RSP_VECTOR_VRSQH: - if (DestReg == RspOp.rt) - { - return true; - } - break; - - case RSP_VECTOR_VCH: - case RSP_VECTOR_VCL: - case RSP_VECTOR_VCR: - case RSP_VECTOR_VMRG: - case RSP_VECTOR_VLT: - case RSP_VECTOR_VEQ: - case RSP_VECTOR_VGE: - case RSP_VECTOR_VNE: - if (DestReg == RspOp.rd) - { - return true; - } - if (DestReg == RspOp.rt) - { - return true; - } - if (DestReg == RspOp.sa) - { - return false; - } - break; - case RSP_VECTOR_VSAW: - if (DestReg == RspOp.sa) - { - return false; - } - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - } - else - { - switch (RspOp.rs) - { - case RSP_COP2_CF: - case RSP_COP2_CT: - break; - case RSP_COP2_MT: - /* if (DestReg == RspOp.rd) { return false; } */ - break; - case RSP_COP2_MF: - if (DestReg == RspOp.rd) - { - return true; - } - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - } - 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: - switch (RspOp.rd) - { - case RSP_LSC2_SV: - case RSP_LSC2_DV: - case RSP_LSC2_RV: - break; - - case RSP_LSC2_QV: - case RSP_LSC2_BV: - case RSP_LSC2_LV: - case RSP_LSC2_TV: - break; - case RSP_LSC2_PV: - case RSP_LSC2_UV: - case RSP_LSC2_HV: - if (DestReg == RspOp.rt) - { - return false; - } - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - break; - case RSP_SC2: - switch (RspOp.rd) - { - case RSP_LSC2_BV: - case RSP_LSC2_SV: - case RSP_LSC2_LV: - case RSP_LSC2_DV: - case RSP_LSC2_QV: - case RSP_LSC2_RV: - case RSP_LSC2_PV: - case RSP_LSC2_UV: - case RSP_LSC2_HV: - case RSP_LSC2_FV: - case RSP_LSC2_WV: - if (DestReg == RspOp.rt) - { - return true; - } - break; - - case RSP_LSC2_TV: - if (8 <= 32 - RspOp.rt) - { - if (DestReg >= RspOp.rt && DestReg <= RspOp.rt + 7) - { - return true; - } - } - else - { - int length = 32 - RspOp.rt, count, del = RspOp.del >> 1, vect = RspOp.rt; - for (count = 0; count < length; count++) - { - if (DestReg == (uint32_t)(vect + del)) - { - return true; - } - del = (del + 1) & 7; - } - } - break; - - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - switch (Instruction_State) - { - case RSPPIPELINE_NORMAL: break; - case RSPPIPELINE_DO_DELAY_SLOT: - Instruction_State = RSPPIPELINE_DELAY_SLOT; - break; - case RSPPIPELINE_DELAY_SLOT: - Instruction_State = RSPPIPELINE_FINISH_BLOCK; - break; - } - } while (Instruction_State != RSPPIPELINE_FINISH_BLOCK); - - /* - This is a tricky situation because most of the - microcode does loops, so looping back and checking - can prove effective, but it's still a branch... - */ - - if (BranchTarget != 0 && RecursiveCall == false) - { - uint32_t BranchTaken, BranchFall; - - // Analysis of branch taken - BranchTaken = WriteToVectorDest2(DestReg, BranchTarget - 4, true); - // Analysis of branch as NOP - BranchFall = WriteToVectorDest2(DestReg, PC, true); - - if (BranchImmed < 0) - { - if (BranchTaken != false) - { - /* - * Took this back branch and found a place - * that needs this vector as a source - */ - return true; - } - else if (BranchFall == HIT_BRANCH) - { - return true; - } - // Otherwise this is completely valid - return BranchFall != 0; - } - else - { - if (BranchFall != false) - { - /* - * Took this forward branch and found a place - * that needs this vector as a source - */ - return true; - } - else if (BranchTaken == HIT_BRANCH) - { - return true; - } - // Otherwise this is completely valid - return BranchTaken != 0; - } - } - - return true; -} - -bool WriteToVectorDest(uint32_t DestReg, int PC) -{ - uint32_t value; - value = WriteToVectorDest2(DestReg, PC, false); - - if (value == HIT_BRANCH) - { - return true; // TODO: ??? - } - else - return value != 0; -} - -/* -UseRspFlags -Output: -True: Flags are determined not in use -False: Either unable to determine or are in use -Input: PC -*/ - -// TODO: Consider delay slots and such in a branch? -bool UseRspFlags(int PC) -{ - RSPOpcode RspOp; - int Instruction_State = NextInstruction; - - if (Compiler.bFlags == false) return true; - - if (Instruction_State == RSPPIPELINE_DELAY_SLOT) - { - return true; - } - - do - { - PC -= 4; - if (PC < 0) - { - return true; - } - RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + (PC & 0xFFC)); - - 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: - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - 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_JR: - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - - default: - CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - break; - case RSP_J: - case RSP_JAL: - case RSP_BEQ: - case RSP_BNE: - case RSP_BLEZ: - case RSP_BGTZ: - Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; - break; - 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: - break; - - case RSP_CP2: - if ((RspOp.rs & 0x10) != 0) - { - switch (RspOp.funct) - { - case RSP_VECTOR_VMULF: - case RSP_VECTOR_VMULU: - case RSP_VECTOR_VMUDL: - case RSP_VECTOR_VMUDM: - case RSP_VECTOR_VMUDN: - case RSP_VECTOR_VMUDH: - break; - case RSP_VECTOR_VMACF: - case RSP_VECTOR_VMACU: - case RSP_VECTOR_VMADL: - case RSP_VECTOR_VMADM: - case RSP_VECTOR_VMADN: - case RSP_VECTOR_VMADH: - break; - - case RSP_VECTOR_VSUB: - case RSP_VECTOR_VADD: - return false; - case RSP_VECTOR_VSUBC: - case RSP_VECTOR_VADDC: - return true; - - case RSP_VECTOR_VABS: - case RSP_VECTOR_VAND: - case RSP_VECTOR_VOR: - case RSP_VECTOR_VXOR: - case RSP_VECTOR_VNAND: - case RSP_VECTOR_VNOR: - case RSP_VECTOR_VNXOR: - case RSP_VECTOR_VRCPH: - case RSP_VECTOR_VRSQL: - case RSP_VECTOR_VRSQH: - case RSP_VECTOR_VRCPL: - case RSP_VECTOR_VRCP: - break; - - case RSP_VECTOR_VCR: - case RSP_VECTOR_VCH: - case RSP_VECTOR_VCL: - case RSP_VECTOR_VLT: - case RSP_VECTOR_VEQ: - case RSP_VECTOR_VGE: - case RSP_VECTOR_VNE: - case RSP_VECTOR_VMRG: - return true; - - case RSP_VECTOR_VSAW: - case RSP_VECTOR_VMOV: - break; - - default: - CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - } - else - { - switch (RspOp.rs) - { - case RSP_COP2_CT: - return true; - - case RSP_COP2_CF: - case RSP_COP2_MT: - case RSP_COP2_MF: - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - } - 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: - switch (RspOp.rd) - { - case RSP_LSC2_BV: - case RSP_LSC2_SV: - case RSP_LSC2_DV: - case RSP_LSC2_RV: - case RSP_LSC2_QV: - case RSP_LSC2_LV: - case RSP_LSC2_UV: - case RSP_LSC2_PV: - case RSP_LSC2_TV: - case RSP_LSC2_HV: - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - break; - case RSP_SC2: - switch (RspOp.rd) - { - case RSP_LSC2_BV: - case RSP_LSC2_SV: - case RSP_LSC2_LV: - case RSP_LSC2_DV: - case RSP_LSC2_QV: - case RSP_LSC2_RV: - case RSP_LSC2_PV: - case RSP_LSC2_UV: - case RSP_LSC2_HV: - case RSP_LSC2_FV: - case RSP_LSC2_WV: - case RSP_LSC2_TV: - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - break; - default: - CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); - return true; - } - switch (Instruction_State) - { - case RSPPIPELINE_NORMAL: break; - case RSPPIPELINE_DO_DELAY_SLOT: - Instruction_State = RSPPIPELINE_DELAY_SLOT; - break; - case RSPPIPELINE_DELAY_SLOT: - Instruction_State = RSPPIPELINE_FINISH_BLOCK; - break; - } - } while (Instruction_State != RSPPIPELINE_FINISH_BLOCK); - return true; -} - /* IsRegisterConstant Output: diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.cpp b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.cpp index 4b8ff9ab8..3b4d3a0b7 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.cpp +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -45,6 +44,7 @@ CRSPRecompiler::CRSPRecompiler(CRSPSystem & System) : m_System(System), m_RSPRegisterHandler(System.m_RSPRegisterHandler), m_OpCode(System.m_OpCode), + m_NextInstruction(RSPPIPELINE_NORMAL), m_IMEM(System.m_IMEM) { } @@ -794,12 +794,12 @@ bool IsJumpLabel(uint32_t PC) return false; } -void CompilerLinkBlocks(void) +void CRSPRecompiler::CompilerLinkBlocks(void) { uint8_t * KnownCode = (uint8_t *)*(JumpTable + (CompilePC >> 2)); CPU_Message("***** Linking block to X86: %08X *****", KnownCode); - NextInstruction = RSPPIPELINE_FINISH_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_BLOCK; // Block linking scenario JmpLabel32("Linked block", 0); @@ -812,7 +812,7 @@ void CRSPRecompiler::CompilerRSPBlock(void) uint8_t * IMEM_SAVE = (uint8_t *)malloc(0x1000); const size_t X86BaseAddress = (size_t)RecompPos; - NextInstruction = RSPPIPELINE_NORMAL; + m_NextInstruction = RSPPIPELINE_NORMAL; CompilePC = *m_System.m_SP_PC_REG; memset(&m_CurrentBlock, 0, sizeof(m_CurrentBlock)); @@ -853,7 +853,7 @@ void CRSPRecompiler::CompilerRSPBlock(void) // Reordering is setup to allow us to have loop labels // so here we see if this is one and put it in the jump table - if (NextInstruction == RSPPIPELINE_NORMAL && IsJumpLabel(CompilePC)) + if (m_NextInstruction == RSPPIPELINE_NORMAL && IsJumpLabel(CompilePC)) { // Jumps come around twice if (NULL == *(JumpTable + (CompilePC >> 2))) @@ -866,7 +866,7 @@ void CRSPRecompiler::CompilerRSPBlock(void) m_CurrentBlock.CurrPC = CompilePC; ReOrderSubBlock(&m_CurrentBlock); } - else if (NextInstruction != RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction != RSPPIPELINE_DELAY_SLOT_DONE) { // We could link the blocks here, but performance-wise it might be better to just let it run @@ -892,36 +892,36 @@ void CRSPRecompiler::CompilerRSPBlock(void) if (m_OpCode.Value == 0xFFFFFFFF) { // I think this pops up an unknown OP dialog - // NextInstruction = RSPPIPELINE_FINISH_BLOCK; + // m_NextInstruction = RSPPIPELINE_FINISH_BLOCK; } else { (RecompilerOps.*RSP_Recomp_Opcode[m_OpCode.op])(); } - switch (NextInstruction) + switch (m_NextInstruction) { case RSPPIPELINE_NORMAL: CompilePC += 4; break; case RSPPIPELINE_DO_DELAY_SLOT: - NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; CompilePC += 4; break; case RSPPIPELINE_DELAY_SLOT: - NextInstruction = RSPPIPELINE_DELAY_SLOT_DONE; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT_DONE; CompilePC = (CompilePC - 4 & 0xFFC); break; case RSPPIPELINE_DELAY_SLOT_EXIT: - NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT_DONE; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT_DONE; CompilePC = (CompilePC - 4 & 0xFFC); break; case RSPPIPELINE_FINISH_SUB_BLOCK: - NextInstruction = RSPPIPELINE_NORMAL; + m_NextInstruction = RSPPIPELINE_NORMAL; CompilePC += 8; if (CompilePC >= 0x1000) { - NextInstruction = RSPPIPELINE_FINISH_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_BLOCK; } else if (NULL == *(JumpTable + (CompilePC >> 2))) { @@ -941,7 +941,7 @@ void CRSPRecompiler::CompilerRSPBlock(void) case RSPPIPELINE_FINISH_BLOCK: break; default: - g_Notify->DisplayError(stdstr_f("RSP main loop\n\nWTF NextInstruction = %d", NextInstruction).c_str()); + g_Notify->DisplayError(stdstr_f("RSP main loop\n\nWTF m_NextInstruction = %d", m_NextInstruction).c_str()); CompilePC += 4; break; } @@ -951,7 +951,7 @@ void CRSPRecompiler::CompilerRSPBlock(void) CompilePC = 0; EndPC = *m_System.m_SP_PC_REG; } - } while (NextInstruction != RSPPIPELINE_FINISH_BLOCK && (CompilePC < EndPC || NextInstruction == RSPPIPELINE_DELAY_SLOT || NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE)); + } while (m_NextInstruction != RSPPIPELINE_FINISH_BLOCK && (CompilePC < EndPC || m_NextInstruction == RSPPIPELINE_DELAY_SLOT || m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE)); if (CompilePC >= EndPC) { MoveConstToVariable((CompilePC & 0xFFC), m_System.m_SP_PC_REG, "RSP PC"); @@ -1041,7 +1041,7 @@ void CRSPRecompiler::RunCPU(void) { StopTimer(); } - if (RSP_NextInstruction == RSPPIPELINE_SINGLE_STEP) + if (m_System.m_NextInstruction == RSPPIPELINE_SINGLE_STEP) { RSP_Running = false; } diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.h b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.h index cf613b0e0..b57d20826 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.h +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -37,6 +38,7 @@ private: CRSPRecompiler(const CRSPRecompiler &); CRSPRecompiler & operator=(const CRSPRecompiler &); + void CompilerLinkBlocks(void); void CompilerRSPBlock(void); void LinkBranches(RSP_BLOCK * Block); void ReOrderSubBlock(RSP_BLOCK * Block); @@ -47,10 +49,11 @@ private: RSPRegisterHandlerPlugin *& m_RSPRegisterHandler; RSPOpcode & m_OpCode; RSP_BLOCK m_CurrentBlock; + RSPPIPELINE_STAGE m_NextInstruction; uint8_t *& m_IMEM; }; -extern uint32_t CompilePC, NextInstruction, JumpTableSize; +extern uint32_t CompilePC, JumpTableSize; extern bool ChangedPC; #define CompilerWarning \ diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp index 6e4112e28..b09f6bed0 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -145,7 +144,7 @@ void CRSPRecompilerOps::CompileBranchExit(uint32_t TargetPC, uint32_t ContinuePC { uint32_t * X86Loc = NULL; - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; CompConstToVariable(true, &BranchCompare, "BranchCompare"); JeLabel32("BranchEqual", 0); X86Loc = (uint32_t *)(RecompPos - 4); @@ -162,6 +161,7 @@ CRSPRecompilerOps::CRSPRecompilerOps(CRSPSystem & System, CRSPRecompiler & Recom m_System(System), m_RSPRegisterHandler(System.m_RSPRegisterHandler), m_Recompiler(Recompiler), + m_NextInstruction(Recompiler.m_NextInstruction), m_OpCode(System.m_OpCode), m_Reg(System.m_Reg), m_GPR(System.m_Reg.m_GPR), @@ -185,39 +185,39 @@ void CRSPRecompilerOps::REGIMM(void) void CRSPRecompilerOps::J(void) { - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { JmpLabel32("BranchToJump", 0); m_Recompiler.Branch_AddRef((m_OpCode.target << 2) & 0xFFC, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { MoveConstToVariable((m_OpCode.target << 2) & 0xFFC, m_System.m_SP_PC_REG, "RSP PC"); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; Ret(); } else { - CompilerWarning(stdstr_f("J error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("J error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } void CRSPRecompilerOps::JAL(void) { - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); MoveConstToVariable((CompilePC + 8) & 0xFFC, &m_GPR[31].UW, "RA.W"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { // Before we branch quickly update our stats if (Profiling && IndvidualBlock) @@ -232,17 +232,17 @@ void CRSPRecompilerOps::JAL(void) } JmpLabel32("BranchToJump", 0); m_Recompiler.Branch_AddRef((m_OpCode.target << 2) & 0xFFC, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { MoveConstToVariable((m_OpCode.target << 2) & 0xFFC, m_System.m_SP_PC_REG, "RSP PC"); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; Ret(); } else { - CompilerWarning(stdstr_f("J error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("J error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } @@ -251,19 +251,19 @@ void CRSPRecompilerOps::BEQ(void) { static bool bDelayAffect; - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); if (m_OpCode.rs == 0 && m_OpCode.rt == 0) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; MoveConstByteToVariable(1, &BranchCompare, "BranchCompare"); return; } bDelayAffect = DelaySlotAffectBranch(CompilePC); if (!bDelayAffect) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } if (m_OpCode.rt == 0) @@ -280,9 +280,9 @@ void CRSPRecompilerOps::BEQ(void) CompX86regToVariable(x86_EAX, &m_GPR[m_OpCode.rs].W, GPR_Name(m_OpCode.rs)); } SetzVariable(&BranchCompare, "BranchCompare"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; @@ -290,7 +290,7 @@ void CRSPRecompilerOps::BEQ(void) { JmpLabel32("BranchToJump", 0); m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; return; } if (!bDelayAffect) @@ -317,16 +317,16 @@ void CRSPRecompilerOps::BEQ(void) JeLabel32("BranchEqual", 0); } m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; CompileBranchExit(Target, CompilePC + 8); } else { - CompilerWarning(stdstr_f("BEQ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("BEQ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } @@ -335,20 +335,20 @@ void CRSPRecompilerOps::BNE(void) { static bool bDelayAffect; - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); if (m_OpCode.rs == 0 && m_OpCode.rt == 0) { MoveConstByteToVariable(0, &BranchCompare, "BranchCompare"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } bDelayAffect = DelaySlotAffectBranch(CompilePC); if (!bDelayAffect) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } if (m_OpCode.rt == 0) @@ -365,15 +365,15 @@ void CRSPRecompilerOps::BNE(void) CompX86regToVariable(x86_EAX, &m_GPR[m_OpCode.rs].W, GPR_Name(m_OpCode.rs)); } SetnzVariable(&BranchCompare, "BranchCompare"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; if (m_OpCode.rs == 0 && m_OpCode.rt == 0) { - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; return; } @@ -401,16 +401,16 @@ void CRSPRecompilerOps::BNE(void) JeLabel32("BranchNotEqual", 0); } m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; CompileBranchExit(Target, CompilePC + 8); } else { - CompilerWarning(stdstr_f("BNE error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("BNE error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } @@ -419,25 +419,25 @@ void CRSPRecompilerOps::BLEZ(void) { static bool bDelayAffect; - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); if (m_OpCode.rs == 0) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } bDelayAffect = DelaySlotAffectBranch(CompilePC); if (!bDelayAffect) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } CompConstToVariable(0, &m_GPR[m_OpCode.rs].W, GPR_Name(m_OpCode.rs)); SetleVariable(&BranchCompare, "BranchCompare"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; @@ -445,7 +445,7 @@ void CRSPRecompilerOps::BLEZ(void) { JmpLabel32("BranchToJump", 0); m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; return; } if (!bDelayAffect) @@ -461,16 +461,16 @@ void CRSPRecompilerOps::BLEZ(void) } m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; CompileBranchExit(Target, CompilePC + 8); } else { - CompilerWarning(stdstr_f("BLEZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("BLEZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } @@ -479,31 +479,31 @@ void CRSPRecompilerOps::BGTZ(void) { static bool bDelayAffect; - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); if (m_OpCode.rs == 0) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } bDelayAffect = DelaySlotAffectBranch(CompilePC); if (!bDelayAffect) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } CompConstToVariable(0, &m_GPR[m_OpCode.rs].W, GPR_Name(m_OpCode.rs)); SetgVariable(&BranchCompare, "BranchCompare"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; if (m_OpCode.rs == 0) { - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; return; } if (!bDelayAffect) @@ -518,16 +518,16 @@ void CRSPRecompilerOps::BGTZ(void) JeLabel32("BranchGreater", 0); } m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; CompileBranchExit(Target, CompilePC + 8); } else { - CompilerWarning(stdstr_f("BGTZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("BGTZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } @@ -1488,7 +1488,7 @@ void CRSPRecompilerOps::Special_JR(void) { uint8_t * Jump; - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); // Transfer destination to location pointed to by m_System.m_SP_PC_REG @@ -1496,9 +1496,9 @@ void CRSPRecompilerOps::Special_JR(void) AndConstToX86Reg(x86_EAX, 0xFFC); MoveX86regToVariable(x86_EAX, m_System.m_SP_PC_REG, "RSP PC"); ChangedPC = true; - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { MoveVariableToX86reg(m_System.m_SP_PC_REG, "RSP PC", x86_EAX); if (Profiling && IndvidualBlock) @@ -1528,16 +1528,16 @@ void CRSPRecompilerOps::Special_JR(void) CPU_Message(" Null:"); Ret(); ChangedPC = false; - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; Ret(); } else { - CompilerWarning(stdstr_f("WTF\n\nJR\nNextInstruction = %X", NextInstruction).c_str()); + CompilerWarning(stdstr_f("WTF\n\nJR\nNextInstruction = %X", m_NextInstruction).c_str()); BreakPoint(); } } @@ -1547,16 +1547,16 @@ void CRSPRecompilerOps::Special_JALR(void) uint8_t * Jump; uint32_t Const = (CompilePC + 8) & 0xFFC; - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); MoveVariableToX86reg(&m_GPR[m_OpCode.rs].W, GPR_Name(m_OpCode.rs), x86_EAX); AndConstToX86Reg(x86_EAX, 0xFFC); MoveX86regToVariable(x86_EAX, m_System.m_SP_PC_REG, "RSP PC"); MoveConstToVariable(Const, &m_GPR[m_OpCode.rd].W, GPR_Name(m_OpCode.rd)); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { MoveVariableToX86reg(m_System.m_SP_PC_REG, "RSP PC", x86_EAX); AddVariableToX86reg(x86_EAX, &JumpTable, "JumpTable"); @@ -1570,16 +1570,16 @@ void CRSPRecompilerOps::Special_JALR(void) x86_SetBranch8b(Jump, RecompPos); CPU_Message(" Null:"); Ret(); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; Ret(); } else { - CompilerWarning(stdstr_f("WTF\n\nJALR\nNextInstruction = %X", NextInstruction).c_str()); + CompilerWarning(stdstr_f("WTF\n\nJALR\nNextInstruction = %X", m_NextInstruction).c_str()); BreakPoint(); } } @@ -1587,19 +1587,19 @@ void CRSPRecompilerOps::Special_JALR(void) void CRSPRecompilerOps::Special_BREAK(void) { Cheat_r4300iOpcode(&RSPOp::Special_BREAK, "RSPOp::Special_BREAK"); - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { MoveConstToVariable(CompilePC + 4, m_System.m_SP_PC_REG, "RSP PC"); Ret(); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT) { - NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; } else { - CompilerWarning(stdstr_f("WTF\n\nBREAK\nNextInstruction = %X", NextInstruction).c_str()); + CompilerWarning(stdstr_f("WTF\n\nBREAK\nNextInstruction = %X", m_NextInstruction).c_str()); BreakPoint(); } } @@ -1942,31 +1942,31 @@ void CRSPRecompilerOps::RegImm_BLTZ(void) { static bool bDelayAffect; - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); if (m_OpCode.rs == 0) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } bDelayAffect = DelaySlotAffectBranch(CompilePC); if (!bDelayAffect) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } CompConstToVariable(0, &m_GPR[m_OpCode.rs].W, GPR_Name(m_OpCode.rs)); SetlVariable(&BranchCompare, "BranchCompare"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; if (m_OpCode.rs == 0) { - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; return; } if (!bDelayAffect) @@ -1981,16 +1981,16 @@ void CRSPRecompilerOps::RegImm_BLTZ(void) JeLabel32("BranchLess", 0); } m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; CompileBranchExit(Target, CompilePC + 8); } else { - CompilerWarning(stdstr_f("BLTZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nPC = %X\nEmulation will now stop", NextInstruction, CompilePC).c_str()); + CompilerWarning(stdstr_f("BLTZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nPC = %X\nEmulation will now stop", m_NextInstruction, CompilePC).c_str()); BreakPoint(); } } @@ -1999,25 +1999,25 @@ void CRSPRecompilerOps::RegImm_BGEZ(void) { static bool bDelayAffect; - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); if (m_OpCode.rs == 0) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } bDelayAffect = DelaySlotAffectBranch(CompilePC); if (!bDelayAffect) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } CompConstToVariable(0, &m_GPR[m_OpCode.rs].W, GPR_Name(m_OpCode.rs)); SetgeVariable(&BranchCompare, "BranchCompare"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; @@ -2025,7 +2025,7 @@ void CRSPRecompilerOps::RegImm_BGEZ(void) { JmpLabel32("BranchToJump", 0); m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; return; } if (!bDelayAffect) @@ -2040,43 +2040,43 @@ void CRSPRecompilerOps::RegImm_BGEZ(void) JeLabel32("BranchGreaterEqual", 0); } m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; CompileBranchExit(Target, CompilePC + 8); } else { - CompilerWarning(stdstr_f("BGEZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("BGEZ error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } void CRSPRecompilerOps::RegImm_BLTZAL(void) { - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); if (m_OpCode.rs == 0) { MoveConstToVariable((CompilePC + 8) & 0xFFC, &m_GPR[31].UW, "RA.W"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } CompConstToVariable(0, &m_GPR[m_OpCode.rs].W, GPR_Name(m_OpCode.rs)); SetlVariable(&BranchCompare, "BranchCompare"); MoveConstToVariable((CompilePC + 8) & 0xFFC, &m_GPR[31].UW, "RA.W"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; if (m_OpCode.rs == 0) { - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; return; } @@ -2084,16 +2084,16 @@ void CRSPRecompilerOps::RegImm_BLTZAL(void) CompConstToVariable(true, &BranchCompare, "BranchCompare"); JeLabel32("BranchLessEqual", 0); m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; CompileBranchExit(Target, CompilePC + 8); } else { - CompilerWarning(stdstr_f("BLTZAL error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("BLTZAL error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } @@ -2102,27 +2102,27 @@ void CRSPRecompilerOps::RegImm_BGEZAL(void) { static bool bDelayAffect; - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { CPU_Message(" %X %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); if (m_OpCode.rs == 0) { MoveConstToVariable((CompilePC + 8) & 0xFFC, &m_GPR[31].UW, "RA.W"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } bDelayAffect = DelaySlotAffectBranch(CompilePC); if (!bDelayAffect) { - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; return; } CompConstToVariable(0, &m_GPR[m_OpCode.rs].W, GPR_Name(m_OpCode.rs)); SetgeVariable(&BranchCompare, "BranchCompare"); MoveConstToVariable((CompilePC + 8) & 0xFFC, &m_GPR[31].UW, "RA.W"); - NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; @@ -2130,7 +2130,7 @@ void CRSPRecompilerOps::RegImm_BGEZAL(void) { JmpLabel32("BranchToJump", 0); m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; return; } if (!bDelayAffect) @@ -2146,16 +2146,16 @@ void CRSPRecompilerOps::RegImm_BGEZAL(void) JeLabel32("BranchGreaterEqual", 0); } m_Recompiler.Branch_AddRef(Target, (uint32_t *)(RecompPos - 4)); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE) { uint32_t Target = (CompilePC + ((short)m_OpCode.offset << 2) + 4) & 0xFFC; CompileBranchExit(Target, CompilePC + 8); } else { - CompilerWarning(stdstr_f("BGEZAL error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("BGEZAL error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } @@ -2179,19 +2179,19 @@ void CRSPRecompilerOps::Cop0_MF(void) #ifndef Compile_Cop0 Cheat_r4300iOpcode(RSP_Cop0_MF, "RSP_Cop0_MF"); - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { MoveConstToVariable(CompilePC + 4, m_System.m_SP_PC_REG, "RSP PC"); Ret(); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT) { - NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; } else { - CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } return; @@ -2247,19 +2247,19 @@ void CRSPRecompilerOps::Cop0_MF(void) MoveConstToVariable(0, &RSP_Running, "RSP_Running"); MoveConstToVariable(1, RSPInfo.SP_SEMAPHORE_REG, "SP_SEMAPHORE_REG"); MoveX86regToVariable(x86_EAX, &m_GPR[m_OpCode.rt].W, GPR_Name(m_OpCode.rt)); - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { MoveConstToVariable(CompilePC + 4, m_System.m_SP_PC_REG, "RSP PC"); Ret(); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT) { - NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; } else { - CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } @@ -2315,19 +2315,19 @@ void CRSPRecompilerOps::Cop0_MT(void) Cheat_r4300iOpcode(RSP_Cop0_MT, "RSP_Cop0_MT"); if (m_OpCode.rd == 4) { - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { MoveConstToVariable(CompilePC + 4, m_System.m_SP_PC_REG, "RSP PC"); Ret(); - NextInstruction = RSPPIPELINE_FINISH_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT) { - NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; } else { - CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } } @@ -2368,19 +2368,19 @@ void CRSPRecompilerOps::Cop0_MT(void) Push(x86_EAX); PushImm32("RSPRegister_STATUS", RSPRegister_STATUS); Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::WriteReg), "RSPRegisterHandlerPlugin::WriteReg"); - if (NextInstruction == RSPPIPELINE_NORMAL) + if (m_NextInstruction == RSPPIPELINE_NORMAL) { MoveConstToVariable(CompilePC + 4, m_System.m_SP_PC_REG, "RSP PC"); Ret(); - NextInstruction = RSPPIPELINE_FINISH_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_BLOCK; } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT) + else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT) { - NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; } else { - CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", m_NextInstruction).c_str()); BreakPoint(); } break; @@ -2605,6 +2605,1068 @@ void CRSPRecompilerOps::COP2_VECTOR(void) UDWORD MMX_Scratch; +bool CRSPRecompilerOps::IsNextInstructionMmx(uint32_t PC) +{ + RSPOpcode RspOp; + + if (!IsMmxEnabled) + { + return false; + } + + PC += 4; + if (PC >= 0x1000) return false; + RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + (PC & 0xFFC)); + + if (RspOp.op != RSP_CP2) + { + return false; + } + + if ((RspOp.rs & 0x10) != 0) + { + switch (RspOp.funct) + { + case RSP_VECTOR_VMULF: + case RSP_VECTOR_VMUDL: // Warning: Not all handled? + case RSP_VECTOR_VMUDM: + case RSP_VECTOR_VMUDN: + case RSP_VECTOR_VMUDH: + if (true == WriteToAccum(7, PC)) + { + return false; + } + else if ((RspOp.rs & 0x0f) >= 2 && (RspOp.rs & 0x0f) <= 7 && IsMmx2Enabled == false) + { + return false; + } + else + return true; + + case RSP_VECTOR_VABS: + case RSP_VECTOR_VAND: + case RSP_VECTOR_VOR: + case RSP_VECTOR_VXOR: + case RSP_VECTOR_VNAND: + case RSP_VECTOR_VNOR: + case RSP_VECTOR_VNXOR: + if (true == WriteToAccum(Low16BitAccum, PC)) + { + return false; + } + else if ((RspOp.rs & 0x0f) >= 2 && (RspOp.rs & 0x0f) <= 7 && IsMmx2Enabled == false) + { + return false; + } + else + return true; + + case RSP_VECTOR_VADD: + case RSP_VECTOR_VSUB: + // Requires no accumulator write, and no flags! + if (WriteToAccum(Low16BitAccum, PC) == true) + { + return false; + } + else if (UseRspFlags(PC) == true) + { + return false; + } + else if ((RspOp.rs & 0x0f) >= 2 && (RspOp.rs & 0x0f) <= 7 && IsMmx2Enabled == false) + { + return false; + } + else + return true; + + default: + return false; + } + } + else + { + return false; + } +} + +bool CRSPRecompilerOps::UseRspFlags(int PC) +{ + RSPOpcode RspOp; + int Instruction_State = m_NextInstruction; + + if (Compiler.bFlags == false) return true; + + if (Instruction_State == RSPPIPELINE_DELAY_SLOT) + { + return true; + } + + do + { + PC -= 4; + if (PC < 0) + { + return true; + } + RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + (PC & 0xFFC)); + + 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: + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + 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_JR: + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + break; + case RSP_J: + case RSP_JAL: + case RSP_BEQ: + case RSP_BNE: + case RSP_BLEZ: + case RSP_BGTZ: + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + 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: + break; + + case RSP_CP2: + if ((RspOp.rs & 0x10) != 0) + { + switch (RspOp.funct) + { + case RSP_VECTOR_VMULF: + case RSP_VECTOR_VMULU: + case RSP_VECTOR_VMUDL: + case RSP_VECTOR_VMUDM: + case RSP_VECTOR_VMUDN: + case RSP_VECTOR_VMUDH: + break; + case RSP_VECTOR_VMACF: + case RSP_VECTOR_VMACU: + case RSP_VECTOR_VMADL: + case RSP_VECTOR_VMADM: + case RSP_VECTOR_VMADN: + case RSP_VECTOR_VMADH: + break; + + case RSP_VECTOR_VSUB: + case RSP_VECTOR_VADD: + return false; + case RSP_VECTOR_VSUBC: + case RSP_VECTOR_VADDC: + return true; + + case RSP_VECTOR_VABS: + case RSP_VECTOR_VAND: + case RSP_VECTOR_VOR: + case RSP_VECTOR_VXOR: + case RSP_VECTOR_VNAND: + case RSP_VECTOR_VNOR: + case RSP_VECTOR_VNXOR: + case RSP_VECTOR_VRCPH: + case RSP_VECTOR_VRSQL: + case RSP_VECTOR_VRSQH: + case RSP_VECTOR_VRCPL: + case RSP_VECTOR_VRCP: + break; + + case RSP_VECTOR_VCR: + case RSP_VECTOR_VCH: + case RSP_VECTOR_VCL: + case RSP_VECTOR_VLT: + case RSP_VECTOR_VEQ: + case RSP_VECTOR_VGE: + case RSP_VECTOR_VNE: + case RSP_VECTOR_VMRG: + return true; + + case RSP_VECTOR_VSAW: + case RSP_VECTOR_VMOV: + break; + + default: + CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + } + else + { + switch (RspOp.rs) + { + case RSP_COP2_CT: + return true; + + case RSP_COP2_CF: + case RSP_COP2_MT: + case RSP_COP2_MF: + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + } + 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: + switch (RspOp.rd) + { + case RSP_LSC2_BV: + case RSP_LSC2_SV: + case RSP_LSC2_DV: + case RSP_LSC2_RV: + case RSP_LSC2_QV: + case RSP_LSC2_LV: + case RSP_LSC2_UV: + case RSP_LSC2_PV: + case RSP_LSC2_TV: + case RSP_LSC2_HV: + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + break; + case RSP_SC2: + switch (RspOp.rd) + { + case RSP_LSC2_BV: + case RSP_LSC2_SV: + case RSP_LSC2_LV: + case RSP_LSC2_DV: + case RSP_LSC2_QV: + case RSP_LSC2_RV: + case RSP_LSC2_PV: + case RSP_LSC2_UV: + case RSP_LSC2_HV: + case RSP_LSC2_FV: + case RSP_LSC2_WV: + case RSP_LSC2_TV: + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in UseRspFlags\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + switch (Instruction_State) + { + case RSPPIPELINE_NORMAL: break; + case RSPPIPELINE_DO_DELAY_SLOT: + Instruction_State = RSPPIPELINE_DELAY_SLOT; + break; + case RSPPIPELINE_DELAY_SLOT: + Instruction_State = RSPPIPELINE_FINISH_BLOCK; + break; + } + } while (Instruction_State != RSPPIPELINE_FINISH_BLOCK); + return true; +} + +bool CRSPRecompilerOps::WriteToAccum(int Location, int PC) +{ + uint32_t value = WriteToAccum2(Location, PC, false); + + if (value == HIT_BRANCH) + { + return true; /* ??? */ + } + else + return value != 0; +} + +uint32_t CRSPRecompilerOps::WriteToAccum2(int Location, int PC, bool RecursiveCall) +{ + RSPOpcode RspOp; + uint32_t BranchTarget = 0; + signed int BranchImmed = 0; + int Instruction_State = m_NextInstruction; + + if (Compiler.bAccum == false) return true; + + if (Instruction_State == RSPPIPELINE_DELAY_SLOT) + { + return true; + } + + do + { + PC += 4; + if (PC >= 0x1000) + { + return true; + } + RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + (PC & 0xFFC)); + + 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: + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + 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: + return true; + + case RSP_SPECIAL_JR: + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + break; + case RSP_J: + // There is no way a loopback is going to use accumulator + if (Compiler.bAudioUcode && (((int)(RspOp.target << 2) & 0xFFC) < PC)) + { + return false; + } + // Rarely occurs, so we let them have their way + else + { + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + } + + case RSP_JAL: + // There is no way calling a subroutine is going to use an accumulator + // or come back and continue an existing calculation + if (Compiler.bAudioUcode) + { + break; + } + else + { + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + } + + case RSP_BEQ: + case RSP_BNE: + case RSP_BLEZ: + case RSP_BGTZ: + BranchImmed = (short)RspOp.offset; + if (Compiler.bAudioUcode) + { + RSPOpcode NextOp; + + // Ignore backward branches and pretend it's a NOP + if (BranchImmed <= 0) + { + break; + } + // If the opcode (which is 8 bytes before the destination and also a J backward) then ignore this + BranchImmed = (PC + ((short)RspOp.offset << 2) + 4) & 0xFFC; + NextOp.Value = *(uint32_t *)(RSPInfo.IMEM + ((BranchImmed - 8) & 0xFFC)); + + if (RspOp.op == RSP_J && (int)(RspOp.target << 2) < PC) + { + break; + } + } + BranchTarget = (PC + ((short)RspOp.offset << 2) + 4) & 0xFFC; + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + 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: + break; + + case RSP_CP2: + if ((RspOp.rs & 0x10) != 0) + { + switch (RspOp.funct) + { + case RSP_VECTOR_VMULF: + case RSP_VECTOR_VMULU: + case RSP_VECTOR_VMUDL: + case RSP_VECTOR_VMUDM: + case RSP_VECTOR_VMUDN: + case RSP_VECTOR_VMUDH: + return false; + case RSP_VECTOR_VMACF: + case RSP_VECTOR_VMACU: + case RSP_VECTOR_VMADL: + case RSP_VECTOR_VMADM: + case RSP_VECTOR_VMADN: + return true; + case RSP_VECTOR_VMADH: + if (Location == Low16BitAccum) + { + break; + } + return true; + + case RSP_VECTOR_VABS: + case RSP_VECTOR_VADD: + case RSP_VECTOR_VADDC: + case RSP_VECTOR_VSUB: + case RSP_VECTOR_VSUBC: + case RSP_VECTOR_VAND: + case RSP_VECTOR_VNAND: + case RSP_VECTOR_VOR: + case RSP_VECTOR_VNOR: + case RSP_VECTOR_VXOR: + case RSP_VECTOR_VNXOR: + // Since these modify the accumulator lower-16 bits we can + // safely assume these 'reset' the accumulator no matter what + // return false; + case RSP_VECTOR_VCR: + case RSP_VECTOR_VCH: + case RSP_VECTOR_VCL: + case RSP_VECTOR_VRCP: + case RSP_VECTOR_VRCPL: + case RSP_VECTOR_VRCPH: + case RSP_VECTOR_VRSQL: + case RSP_VECTOR_VRSQH: + case RSP_VECTOR_VLT: + case RSP_VECTOR_VEQ: + case RSP_VECTOR_VGE: + case RSP_VECTOR_VNE: + case RSP_VECTOR_VMRG: + case RSP_VECTOR_VMOV: + if (Location == Low16BitAccum) + { + return false; + } + break; + + case RSP_VECTOR_VSAW: + return true; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + } + else + { + switch (RspOp.rs) + { + case RSP_COP2_CF: + case RSP_COP2_CT: + case RSP_COP2_MT: + case RSP_COP2_MF: + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + } + 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: + switch (RspOp.rd) + { + case RSP_LSC2_BV: + case RSP_LSC2_SV: + case RSP_LSC2_DV: + case RSP_LSC2_RV: + case RSP_LSC2_QV: + case RSP_LSC2_LV: + case RSP_LSC2_UV: + case RSP_LSC2_PV: + case RSP_LSC2_TV: + case RSP_LSC2_HV: + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + break; + case RSP_SC2: + switch (RspOp.rd) + { + case RSP_LSC2_BV: + case RSP_LSC2_SV: + case RSP_LSC2_LV: + case RSP_LSC2_DV: + case RSP_LSC2_QV: + case RSP_LSC2_RV: + case RSP_LSC2_PV: + case RSP_LSC2_UV: + case RSP_LSC2_HV: + case RSP_LSC2_FV: + case RSP_LSC2_WV: + case RSP_LSC2_TV: + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToAccum\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + switch (Instruction_State) + { + case RSPPIPELINE_NORMAL: break; + case RSPPIPELINE_DO_DELAY_SLOT: + Instruction_State = RSPPIPELINE_DELAY_SLOT; + break; + case RSPPIPELINE_DELAY_SLOT: + Instruction_State = RSPPIPELINE_FINISH_BLOCK; + break; + } + } while (Instruction_State != RSPPIPELINE_FINISH_BLOCK); + + /* + This is a tricky situation because most of the + microcode does loops, so looping back and checking + can prove effective, but it's still a branch... + */ + + if (BranchTarget != 0 && RecursiveCall == false) + { + uint32_t BranchTaken, BranchFall; + + // Analysis of branch taken + BranchTaken = WriteToAccum2(Location, BranchTarget - 4, true); + // Analysis of branch as NOP + BranchFall = WriteToAccum2(Location, PC, true); + + if (BranchImmed < 0) + { + if (BranchTaken != false) + { + + // Took this back branch and found a place + // that needs this vector as a source + + return true; + } + else if (BranchFall == HIT_BRANCH) + { + return true; + } + // Otherwise this is completely valid + return BranchFall; + } + else + { + if (BranchFall != false) + { + + // Took this forward branch and found a place + // that needs this vector as a source + + return true; + } + else if (BranchTaken == HIT_BRANCH) + { + return true; + } + // Otherwise this is completely valid + return BranchTaken; + } + } + return true; +} + +bool CRSPRecompilerOps::WriteToVectorDest(uint32_t DestReg, int PC) +{ + uint32_t value; + value = WriteToVectorDest2(DestReg, PC, false); + + if (value == HIT_BRANCH) + { + return true; // TODO: ??? + } + else + { + return value != 0; + } +} + +bool CRSPRecompilerOps::WriteToVectorDest2(uint32_t DestReg, int PC, bool RecursiveCall) +{ + RSPOpcode RspOp; + uint32_t BranchTarget = 0; + signed int BranchImmed = 0; + + int Instruction_State = m_NextInstruction; + + if (Compiler.bDest == false) return true; + + if (Instruction_State == RSPPIPELINE_DELAY_SLOT) + { + return true; + } + + do + { + PC += 4; + if (PC >= 0x1000) + { + return true; + } + RspOp.Value = *(uint32_t *)(RSPInfo.IMEM + (PC & 0xFFC)); + + 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: + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + 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: + return true; + + case RSP_SPECIAL_JR: + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + break; + case RSP_J: + // There is no way a loopback is going to use accumulator + if (Compiler.bAudioUcode && (int)(RspOp.target << 2) < PC) + { + return false; + } + // Rarely occurs, so we let them have their way + return true; + + case RSP_JAL: + // Assume register is being passed to function or used after the function call + return true; + + case RSP_BEQ: + case RSP_BNE: + case RSP_BLEZ: + case RSP_BGTZ: + BranchImmed = (short)RspOp.offset; + if (Compiler.bAudioUcode) + { + RSPOpcode NextOp; + + // Ignore backward branches and pretend it's a NOP + if (BranchImmed <= 0) + { + break; + } + // If the opcode (which is 8 bytes before the destination and also a J backward) then ignore this + BranchImmed = (PC + ((short)RspOp.offset << 2) + 4) & 0xFFC; + RSP_LW_IMEM(BranchImmed - 8, &NextOp.Value); + if (RspOp.op == RSP_J && (int)(RspOp.target << 2) < PC) + { + break; + } + } + BranchTarget = (PC + ((short)RspOp.offset << 2) + 4) & 0xFFC; + Instruction_State = RSPPIPELINE_DO_DELAY_SLOT; + break; + 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: + break; + + case RSP_CP2: + if ((RspOp.rs & 0x10) != 0) + { + switch (RspOp.funct) + { + case RSP_VECTOR_VMULF: + case RSP_VECTOR_VMULU: + case RSP_VECTOR_VMUDL: + case RSP_VECTOR_VMUDM: + case RSP_VECTOR_VMUDN: + case RSP_VECTOR_VMUDH: + case RSP_VECTOR_VMACF: + case RSP_VECTOR_VMACU: + case RSP_VECTOR_VMADL: + case RSP_VECTOR_VMADM: + case RSP_VECTOR_VMADN: + case RSP_VECTOR_VMADH: + case RSP_VECTOR_VADD: + case RSP_VECTOR_VADDC: + case RSP_VECTOR_VSUB: + case RSP_VECTOR_VSUBC: + case RSP_VECTOR_VAND: + case RSP_VECTOR_VNAND: + case RSP_VECTOR_VOR: + case RSP_VECTOR_VNOR: + case RSP_VECTOR_VXOR: + case RSP_VECTOR_VNXOR: + case RSP_VECTOR_VABS: + if (DestReg == RspOp.rd) + { + return true; + } + if (DestReg == RspOp.rt) + { + return true; + } + if (DestReg == RspOp.sa) + { + return false; + } + break; + + case RSP_VECTOR_VMOV: + case RSP_VECTOR_VRCP: + case RSP_VECTOR_VRCPL: + case RSP_VECTOR_VRCPH: + case RSP_VECTOR_VRSQL: + case RSP_VECTOR_VRSQH: + if (DestReg == RspOp.rt) + { + return true; + } + break; + + case RSP_VECTOR_VCH: + case RSP_VECTOR_VCL: + case RSP_VECTOR_VCR: + case RSP_VECTOR_VMRG: + case RSP_VECTOR_VLT: + case RSP_VECTOR_VEQ: + case RSP_VECTOR_VGE: + case RSP_VECTOR_VNE: + if (DestReg == RspOp.rd) + { + return true; + } + if (DestReg == RspOp.rt) + { + return true; + } + if (DestReg == RspOp.sa) + { + return false; + } + break; + case RSP_VECTOR_VSAW: + if (DestReg == RspOp.sa) + { + return false; + } + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + } + else + { + switch (RspOp.rs) + { + case RSP_COP2_CF: + case RSP_COP2_CT: + break; + case RSP_COP2_MT: + /* if (DestReg == RspOp.rd) { return false; } */ + break; + case RSP_COP2_MF: + if (DestReg == RspOp.rd) + { + return true; + } + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + } + 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: + switch (RspOp.rd) + { + case RSP_LSC2_SV: + case RSP_LSC2_DV: + case RSP_LSC2_RV: + break; + + case RSP_LSC2_QV: + case RSP_LSC2_BV: + case RSP_LSC2_LV: + case RSP_LSC2_TV: + break; + case RSP_LSC2_PV: + case RSP_LSC2_UV: + case RSP_LSC2_HV: + if (DestReg == RspOp.rt) + { + return false; + } + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + break; + case RSP_SC2: + switch (RspOp.rd) + { + case RSP_LSC2_BV: + case RSP_LSC2_SV: + case RSP_LSC2_LV: + case RSP_LSC2_DV: + case RSP_LSC2_QV: + case RSP_LSC2_RV: + case RSP_LSC2_PV: + case RSP_LSC2_UV: + case RSP_LSC2_HV: + case RSP_LSC2_FV: + case RSP_LSC2_WV: + if (DestReg == RspOp.rt) + { + return true; + } + break; + + case RSP_LSC2_TV: + if (8 <= 32 - RspOp.rt) + { + if (DestReg >= RspOp.rt && DestReg <= RspOp.rt + 7) + { + return true; + } + } + else + { + int length = 32 - RspOp.rt, count, del = RspOp.del >> 1, vect = RspOp.rt; + for (count = 0; count < length; count++) + { + if (DestReg == (uint32_t)(vect + del)) + { + return true; + } + del = (del + 1) & 7; + } + } + break; + + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + break; + default: + CompilerWarning(stdstr_f("Unknown opcode in WriteToVectorDest\n%s", RSPInstruction(PC, RspOp.Value).NameAndParam().c_str()).c_str()); + return true; + } + switch (Instruction_State) + { + case RSPPIPELINE_NORMAL: break; + case RSPPIPELINE_DO_DELAY_SLOT: + Instruction_State = RSPPIPELINE_DELAY_SLOT; + break; + case RSPPIPELINE_DELAY_SLOT: + Instruction_State = RSPPIPELINE_FINISH_BLOCK; + break; + } + } while (Instruction_State != RSPPIPELINE_FINISH_BLOCK); + + /* + This is a tricky situation because most of the + microcode does loops, so looping back and checking + can prove effective, but it's still a branch... + */ + + if (BranchTarget != 0 && RecursiveCall == false) + { + uint32_t BranchTaken, BranchFall; + + // Analysis of branch taken + BranchTaken = WriteToVectorDest2(DestReg, BranchTarget - 4, true); + // Analysis of branch as NOP + BranchFall = WriteToVectorDest2(DestReg, PC, true); + + if (BranchImmed < 0) + { + if (BranchTaken != false) + { + /* + * Took this back branch and found a place + * that needs this vector as a source + */ + return true; + } + else if (BranchFall == HIT_BRANCH) + { + return true; + } + // Otherwise this is completely valid + return BranchFall != 0; + } + else + { + if (BranchFall != false) + { + /* + * Took this forward branch and found a place + * that needs this vector as a source + */ + return true; + } + else if (BranchTaken == HIT_BRANCH) + { + return true; + } + // Otherwise this is completely valid + return BranchTaken != 0; + } + } + + return true; +} + void CRSPRecompilerOps::RSP_Element2Mmx(int MmxReg) { char Reg[256]; @@ -7241,7 +8303,7 @@ void CRSPRecompilerOps::Opcode_SWV(void) void CRSPRecompilerOps::UnknownOpcode(void) { CPU_Message(" %X Unhandled Opcode: %s", CompilePC, RSPInstruction(CompilePC, m_OpCode.Value).NameAndParam().c_str()); - NextInstruction = RSPPIPELINE_FINISH_BLOCK; + m_NextInstruction = RSPPIPELINE_FINISH_BLOCK; MoveConstToVariable(CompilePC, m_System.m_SP_PC_REG, "RSP PC"); MoveConstToVariable(m_OpCode.Value, &m_OpCode.Value, "m_OpCode.Value"); MoveConstToX86reg((uint32_t) & (RSPSystem.m_Op), x86_ECX); diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.h b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.h index 7b058cd24..78a572c7b 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.h +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.h @@ -6,6 +6,11 @@ class CRSPRegisters; class CRSPRecompilerOps { + enum + { + HIT_BRANCH = 0x2, + }; + public: CRSPRecompilerOps(CRSPSystem & System, CRSPRecompiler & Recompiler); @@ -166,6 +171,12 @@ private: void Cheat_r4300iOpcode(RSPOp::Func FunctAddress, const char * FunctName); void Cheat_r4300iOpcodeNoMessage(RSPOp::Func FunctAddress, const char * FunctName); + bool IsNextInstructionMmx(uint32_t PC); + bool UseRspFlags(int PC); + bool WriteToAccum(int Location, int PC); + uint32_t WriteToAccum2(int Location, int PC, bool RecursiveCall); + bool WriteToVectorDest(uint32_t DestReg, int PC); + bool WriteToVectorDest2(uint32_t DestReg, int PC, bool RecursiveCall); void RSP_Element2Mmx(int MmxReg); void RSP_MultiElement2Mmx(int MmxReg1, int MmxReg2); void CompileBranchExit(uint32_t TargetPC, uint32_t ContinuePC); @@ -206,6 +217,7 @@ private: RSPRegisterHandlerPlugin *& m_RSPRegisterHandler; CRSPRegisters & m_Reg; CRSPRecompiler & m_Recompiler; + RSPPIPELINE_STAGE & m_NextInstruction; RSPOpcode & m_OpCode; UWORD32 * m_GPR; UDWORD * m_ACCUM; diff --git a/Source/Project64-rsp-core/cpu/RSPCpu.cpp b/Source/Project64-rsp-core/cpu/RSPCpu.cpp index 6c4c6ca7c..149d702b8 100644 --- a/Source/Project64-rsp-core/cpu/RSPCpu.cpp +++ b/Source/Project64-rsp-core/cpu/RSPCpu.cpp @@ -12,7 +12,7 @@ class RSPRegisterHandler; UDWORD EleSpec[16], Indx[16]; -uint32_t NextInstruction, RSP_Running; +uint32_t RSP_Running; void BuildRecompilerCPU(void); diff --git a/Source/Project64-rsp-core/cpu/RSPInterpreterCPU.cpp b/Source/Project64-rsp-core/cpu/RSPInterpreterCPU.cpp deleted file mode 100644 index 1be34d013..000000000 --- a/Source/Project64-rsp-core/cpu/RSPInterpreterCPU.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "RSPInterpreterCPU.h" -#include "RSPCpu.h" -#include "RSPInterpreterOps.h" -#include "RSPRegisters.h" -#include -#include -#include -#include - -RSPPIPELINE_STAGE RSP_NextInstruction; -uint32_t RSP_JumpTo; \ No newline at end of file diff --git a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp index d7b87897d..5cf8b6765 100644 --- a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp +++ b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp @@ -1,5 +1,4 @@ #include "RSPCpu.h" -#include "RSPInterpreterCPU.h" #include "RSPRegisters.h" #include "RspLog.h" #include @@ -61,6 +60,8 @@ RSPOp::RSPOp(CRSPSystem & System) : m_RSPRegisterHandler(System.m_RSPRegisterHandler), m_OpCode(System.m_OpCode), m_Reg(System.m_Reg), + m_NextInstruction(System.m_NextInstruction), + m_JumpTo(System.m_JumpTo), m_MI_INTR_REG(System.m_MI_INTR_REG), m_SP_PC_REG(System.m_SP_PC_REG), m_SP_STATUS_REG(System.m_SP_STATUS_REG), @@ -469,39 +470,39 @@ void RSPOp::REGIMM(void) void RSPOp::J(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = (m_OpCode.target << 2) & 0xFFC; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = (m_OpCode.target << 2) & 0xFFC; } void RSPOp::JAL(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; m_GPR[31].UW = (*m_SP_PC_REG + 8) & 0xFFC; - RSP_JumpTo = (m_OpCode.target << 2) & 0xFFC; + m_JumpTo = (m_OpCode.target << 2) & 0xFFC; } void RSPOp::BEQ(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W == m_GPR[m_OpCode.rt].W); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W == m_GPR[m_OpCode.rt].W); } void RSPOp::BNE(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W != m_GPR[m_OpCode.rt].W); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W != m_GPR[m_OpCode.rt].W); } void RSPOp::BLEZ(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W <= 0); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W <= 0); } void RSPOp::BGTZ(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W > 0); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W > 0); } void RSPOp::ADDI(void) @@ -708,14 +709,14 @@ void RSPOp::Special_SRAV(void) void RSPOp::Special_JR(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = (m_GPR[m_OpCode.rs].W & 0xFFC); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = (m_GPR[m_OpCode.rs].W & 0xFFC); } void RSPOp::Special_JALR(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = (m_GPR[m_OpCode.rs].W & 0xFFC); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = (m_GPR[m_OpCode.rs].W & 0xFFC); m_GPR[m_OpCode.rd].W = (*m_SP_PC_REG + 8) & 0xFFC; } @@ -784,27 +785,27 @@ void RSPOp::Special_SLTU(void) void RSPOp::BLTZ(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W < 0); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W < 0); } void RSPOp::BGEZ(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W >= 0); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W >= 0); } void RSPOp::BLTZAL(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W < 0); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W < 0); m_GPR[31].UW = (*m_SP_PC_REG + 8) & 0xFFC; } void RSPOp::BGEZAL(void) { - RSP_NextInstruction = RSPPIPELINE_DELAY_SLOT; - RSP_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W >= 0); + m_NextInstruction = RSPPIPELINE_DELAY_SLOT; + m_JumpTo = BranchIf(m_GPR[m_OpCode.rs].W >= 0); m_GPR[31].UW = (*m_SP_PC_REG + 8) & 0xFFC; } diff --git a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.h b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.h index 23f792016..107bee99a 100644 --- a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.h +++ b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include class CRSPSystem; @@ -186,6 +187,8 @@ private: RSPRegisterHandlerPlugin *& m_RSPRegisterHandler; RSPOpcode & m_OpCode; CRSPRegisters & m_Reg; + RSPPIPELINE_STAGE & m_NextInstruction; + uint32_t & m_JumpTo; uint32_t *& m_MI_INTR_REG; uint32_t *& m_SP_PC_REG; uint32_t *& m_SP_STATUS_REG; diff --git a/Source/Project64-rsp-core/cpu/RSPInterpreterCPU.h b/Source/Project64-rsp-core/cpu/RspPipelineStage.h similarity index 80% rename from Source/Project64-rsp-core/cpu/RSPInterpreterCPU.h rename to Source/Project64-rsp-core/cpu/RspPipelineStage.h index 1a307b68c..2436acd05 100644 --- a/Source/Project64-rsp-core/cpu/RSPInterpreterCPU.h +++ b/Source/Project64-rsp-core/cpu/RspPipelineStage.h @@ -1,4 +1,4 @@ -#include +#pragma once enum RSPPIPELINE_STAGE { @@ -13,7 +13,4 @@ enum RSPPIPELINE_STAGE RSPPIPELINE_SINGLE_STEP_DONE = 8, RSPPIPELINE_FINISH_BLOCK = 9, RSPPIPELINE_FINISH_SUB_BLOCK = 10, -}; - -extern RSPPIPELINE_STAGE RSP_NextInstruction; -extern uint32_t RSP_JumpTo; +}; \ No newline at end of file diff --git a/Source/Project64-rsp-core/cpu/RspSystem.cpp b/Source/Project64-rsp-core/cpu/RspSystem.cpp index 4ae85d7d3..227f37e81 100644 --- a/Source/Project64-rsp-core/cpu/RspSystem.cpp +++ b/Source/Project64-rsp-core/cpu/RspSystem.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -14,6 +13,8 @@ CRSPSystem::CRSPSystem() : m_Recompiler(nullptr), m_RSPRegisterHandler(nullptr), m_Op(*this), + m_NextInstruction(RSPPIPELINE_NORMAL), + m_JumpTo(0), m_HEADER(nullptr), m_RDRAM(nullptr), m_DMEM(nullptr), @@ -127,22 +128,22 @@ uint32_t CRSPSystem::RunInterpreterCPU(uint32_t Cycles) (m_Op.*(m_Op.Jump_Opcode[m_OpCode.op]))(); GprR0 = 0x00000000; // MIPS $zero hard-wired to 0 - switch (RSP_NextInstruction) + switch (m_NextInstruction) { case RSPPIPELINE_NORMAL: ProgramCounter = (ProgramCounter + 4) & 0xFFC; break; case RSPPIPELINE_DELAY_SLOT: - RSP_NextInstruction = RSPPIPELINE_JUMP; + m_NextInstruction = RSPPIPELINE_JUMP; ProgramCounter = (ProgramCounter + 4) & 0xFFC; break; case RSPPIPELINE_JUMP: - RSP_NextInstruction = RSPPIPELINE_NORMAL; - ProgramCounter = RSP_JumpTo; + m_NextInstruction = RSPPIPELINE_NORMAL; + ProgramCounter = m_JumpTo; break; case RSPPIPELINE_SINGLE_STEP: ProgramCounter = (ProgramCounter + 4) & 0xFFC; - RSP_NextInstruction = RSPPIPELINE_SINGLE_STEP_DONE; + m_NextInstruction = RSPPIPELINE_SINGLE_STEP_DONE; break; case RSPPIPELINE_SINGLE_STEP_DONE: ProgramCounter = (ProgramCounter + 4) & 0xFFC; diff --git a/Source/Project64-rsp-core/cpu/RspSystem.h b/Source/Project64-rsp-core/cpu/RspSystem.h index cdc02a344..313966818 100644 --- a/Source/Project64-rsp-core/cpu/RspSystem.h +++ b/Source/Project64-rsp-core/cpu/RspSystem.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,8 @@ private: CRSPRegisters m_Reg; RSPOp m_Op; RSPOpcode m_OpCode; + RSPPIPELINE_STAGE m_NextInstruction; + uint32_t m_JumpTo; uint8_t * m_HEADER; uint8_t * m_RDRAM; uint8_t * m_DMEM;