diff --git a/Source/Project64-core/N64System/CheatClass.cpp b/Source/Project64-core/N64System/CheatClass.cpp index 9680346d4..2a4eaa756 100644 --- a/Source/Project64-core/N64System/CheatClass.cpp +++ b/Source/Project64-core/N64System/CheatClass.cpp @@ -282,7 +282,7 @@ bool CCheats::IsValid16BitCode(const char * CheatString) break; case 0x81000000: case 0xA1000000: - case 0xD1000000: // Added by Witten (witten@pj64cheats.net) + case 0xD1000000: case 0xD3000000: if (((CodeEntry.Command & 0xFFFFFF) & 1) == 1) { @@ -348,7 +348,7 @@ int CCheats::ApplyCheatEntry(CMipsMemoryVM * MMU, const CODES & CodeEntry, int C switch (Code.Command & 0xFF000000) { // Gameshark / AR - case 0x50000000: // Added by Witten (witten@pj64cheats.net) + case 0x50000000: { if ((CurrentEntry + 1) >= (int)CodeEntry.size()) { @@ -404,22 +404,22 @@ int CCheats::ApplyCheatEntry(CMipsMemoryVM * MMU, const CODES & CodeEntry, int C Address = 0xA0000000 | (Code.Command & 0xFFFFFF); if (Execute) { MMU->SH_VAddr(Address, Code.Value); } break; - case 0xD0000000: // Added by Witten (witten@pj64cheats.net) + case 0xD0000000: Address = 0x80000000 | (Code.Command & 0xFFFFFF); MMU->LB_VAddr(Address, bMemory); if (bMemory != Code.Value) { Execute = false; } return ApplyCheatEntry(MMU, CodeEntry, CurrentEntry + 1, Execute) + 1; - case 0xD1000000: // Added by Witten (witten@pj64cheats.net) + case 0xD1000000: Address = 0x80000000 | (Code.Command & 0xFFFFFF); MMU->LH_VAddr(Address, wMemory); if (wMemory != Code.Value) { Execute = false; } return ApplyCheatEntry(MMU, CodeEntry, CurrentEntry + 1, Execute) + 1; - case 0xD2000000: // Added by Witten (witten@pj64cheats.net) + case 0xD2000000: Address = 0x80000000 | (Code.Command & 0xFFFFFF); MMU->LB_VAddr(Address, bMemory); if (bMemory == Code.Value) { Execute = false; } return ApplyCheatEntry(MMU, CodeEntry, CurrentEntry + 1, Execute) + 1; - case 0xD3000000: // Added by Witten (witten@pj64cheats.net) + case 0xD3000000: Address = 0x80000000 | (Code.Command & 0xFFFFFF); MMU->LH_VAddr(Address, wMemory); if (wMemory == Code.Value) { Execute = false; } diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp index 6d8324b36..4f3eff776 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp @@ -378,11 +378,11 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter() Jump_CoP1_S[7] = R4300iOp::COP1_S_NEG; Jump_CoP1_S[8] = R4300iOp::COP1_S_ROUND_L; Jump_CoP1_S[9] = R4300iOp::COP1_S_TRUNC_L; - Jump_CoP1_S[10] = R4300iOp::COP1_S_CEIL_L; //added by Witten - Jump_CoP1_S[11] = R4300iOp::COP1_S_FLOOR_L; //added by Witten + Jump_CoP1_S[10] = R4300iOp::COP1_S_CEIL_L; + Jump_CoP1_S[11] = R4300iOp::COP1_S_FLOOR_L; Jump_CoP1_S[12] = R4300iOp::COP1_S_ROUND_W; Jump_CoP1_S[13] = R4300iOp::COP1_S_TRUNC_W; - Jump_CoP1_S[14] = R4300iOp::COP1_S_CEIL_W; //added by Witten + Jump_CoP1_S[14] = R4300iOp::COP1_S_CEIL_W; Jump_CoP1_S[15] = R4300iOp::COP1_S_FLOOR_W; Jump_CoP1_S[16] = R4300iOp::UnknownOpcode; Jump_CoP1_S[17] = R4300iOp::UnknownOpcode; @@ -442,13 +442,13 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter() Jump_CoP1_D[6] = R4300iOp::COP1_D_MOV; Jump_CoP1_D[7] = R4300iOp::COP1_D_NEG; Jump_CoP1_D[8] = R4300iOp::COP1_D_ROUND_L; - Jump_CoP1_D[9] = R4300iOp::COP1_D_TRUNC_L; //added by Witten - Jump_CoP1_D[10] = R4300iOp::COP1_D_CEIL_L; //added by Witten - Jump_CoP1_D[11] = R4300iOp::COP1_D_FLOOR_L; //added by Witten + Jump_CoP1_D[9] = R4300iOp::COP1_D_TRUNC_L; + Jump_CoP1_D[10] = R4300iOp::COP1_D_CEIL_L; + Jump_CoP1_D[11] = R4300iOp::COP1_D_FLOOR_L; Jump_CoP1_D[12] = R4300iOp::COP1_D_ROUND_W; Jump_CoP1_D[13] = R4300iOp::COP1_D_TRUNC_W; - Jump_CoP1_D[14] = R4300iOp::COP1_D_CEIL_W; //added by Witten - Jump_CoP1_D[15] = R4300iOp::COP1_D_FLOOR_W; //added by Witten + Jump_CoP1_D[14] = R4300iOp::COP1_D_CEIL_W; + Jump_CoP1_D[15] = R4300iOp::COP1_D_FLOOR_W; Jump_CoP1_D[16] = R4300iOp::UnknownOpcode; Jump_CoP1_D[17] = R4300iOp::UnknownOpcode; Jump_CoP1_D[18] = R4300iOp::UnknownOpcode; diff --git a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp index a7691cbfa..6b04c0f2e 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp @@ -26,13 +26,22 @@ CCodeBlock::CCodeBlock(uint32_t VAddrEnter, uint8_t * CompiledLocation) : m_VAddrLast(VAddrEnter), m_CompiledLocation(CompiledLocation), m_EnterSection(NULL), + m_RecompilerOps(NULL), m_Test(1) { + memset(m_MemContents, 0, sizeof(m_MemContents)); + memset(m_MemLocation, 0, sizeof(m_MemLocation)); + CCodeSection * baseSection = new CCodeSection(this, VAddrEnter, 0, false); if (baseSection == NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } + m_RecompilerOps = new CRecompilerOps; + if (m_RecompilerOps == NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } m_Sections.push_back(baseSection); baseSection->AddParent(NULL); @@ -74,6 +83,12 @@ CCodeBlock::~CCodeBlock() delete Section; } m_Sections.clear(); + + if (m_RecompilerOps != NULL) + { + delete m_RecompilerOps; + m_RecompilerOps = NULL; + } } bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSection, uint32_t TargetPC, bool LinkAllowed, uint32_t CurrentPC ) @@ -715,7 +730,7 @@ bool CCodeBlock::Compile() CPU_Message("No of Sections: %d",NoOfSections() ); CPU_Message("====== recompiled code ======"); - m_EnterSection->EnterCodeBlock(); + m_RecompilerOps->EnterCodeBlock(); if (g_System->bLinkBlocks()) { while (m_EnterSection->GenerateNativeCode(NextTest())); @@ -727,7 +742,7 @@ bool CCodeBlock::Compile() return false; } } - m_EnterSection->CompileExitCode(); + m_RecompilerOps->CompileExitCode(); uint32_t PAddr; g_TransVaddr->TranslateVaddr(VAddrFirst(),PAddr); diff --git a/Source/Project64-core/N64System/Recompiler/CodeBlock.h b/Source/Project64-core/N64System/Recompiler/CodeBlock.h index e651e6c52..e39dd68f6 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeBlock.h +++ b/Source/Project64-core/N64System/Recompiler/CodeBlock.h @@ -28,7 +28,7 @@ public: int32_t NoOfSections() const { return m_Sections.size() - 1;} const CCodeSection & EnterSection() const { return *m_EnterSection; } const MD5Digest & Hash() const { return m_Hash; } - CRecompilerOps * RecompilerOps() { return m_EnterSection; } + CRecompilerOps *& RecompilerOps() { return m_RecompilerOps; } void SetVAddrFirst(uint32_t VAddr) { m_VAddrFirst = VAddr; } void SetVAddrLast(uint32_t VAddr) { m_VAddrLast = VAddr; } @@ -69,4 +69,5 @@ private: MD5Digest m_Hash; uint64_t m_MemContents[2]; uint64_t * m_MemLocation[2]; + CRecompilerOps * m_RecompilerOps; }; diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp index 495975f09..9a2cd1fda 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp @@ -30,9 +30,9 @@ static bool DelaySlotEffectsJump(uint32_t JumpPC) OPCODE Command; if (!g_MMU->LW_VAddr(JumpPC, Command.Hex)) - { + { return true; - } + } switch (Command.op) { @@ -122,9 +122,11 @@ CCodeSection::CCodeSection(CCodeBlock * CodeBlock, uint32_t EnterPC, uint32_t ID m_Test2(0), m_CompiledLocation(NULL), m_InLoop(false), - m_DelaySlot(false) + m_DelaySlot(false), + m_RecompilerOps(CodeBlock->RecompilerOps()) { CPU_Message("%s: ID %d EnterPC 0x%08X", __FUNCTION__, ID, EnterPC); + m_RecompilerOps->SetCurrentSection(this); } CCodeSection::~CCodeSection() @@ -146,7 +148,7 @@ void CCodeSection::GenerateSectionLinkage() } } - if ((CompilePC() & 0xFFC) == 0xFFC) + if ((m_RecompilerOps->GetCurrentPC() & 0xFFC) == 0xFFC) { g_Notify->BreakPoint(__FILE__, __LINE__); #ifdef legacycode @@ -195,16 +197,16 @@ void CCodeSection::GenerateSectionLinkage() CPU_Message(" $FinishBlock:"); SetJump8(Jump,*g_RecompPos); } - //MoveConstToVariable(CompilePC() + 4,_PROGRAM_COUNTER,"PROGRAM_COUNTER"); + //MoveConstToVariable(m_RecompilerOps->GetCurrentPC() + 4,_PROGRAM_COUNTER,"PROGRAM_COUNTER"); m_RegWorkingSet.WriteBackRegisters(); - UpdateCounters(m_RegWorkingSet,false,true); + m_RecompilerOps->UpdateCounters(m_RegWorkingSet,false,true); // WriteBackRegisters(Section); // if (g_SyncSystem) { MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); //} // MoveConstToVariable(DELAY_SLOT,&m_NextInstruction,"m_NextInstruction"); - PushImm32(stdstr_f("0x%08X",CompilePC() + 4).c_str(),CompilePC() + 4); + PushImm32(stdstr_f("0x%08X",m_RecompilerOps->GetCurrentPC() + 4).c_str(),m_RecompilerOps->GetCurrentPC() + 4); // check if there is an existing section @@ -217,18 +219,11 @@ void CCodeSection::GenerateSectionLinkage() } // Handle Perm Loop - if (CRecompilerOps::m_CompilePC == m_Jump.TargetPC && (m_Cont.FallThrough == false)) + if (m_RecompilerOps->GetCurrentPC() == m_Jump.TargetPC && (m_Cont.FallThrough == false)) { - if (!DelaySlotEffectsJump(CompilePC())) + if (!DelaySlotEffectsJump(m_RecompilerOps->GetCurrentPC())) { - MoveConstToVariable(CompilePC(), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - m_Jump.RegSet.WriteBackRegisters(); - UpdateCounters(m_Jump.RegSet, false, true); - Call_Direct(AddressOf(CInterpreterCPU::InPermLoop), "CInterpreterCPU::InPermLoop"); - MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); - Call_Direct(AddressOf(&CSystemTimer::TimerDone), "CSystemTimer::TimerDone"); - CPU_Message("CompileSystemCheck 3"); - CompileSystemCheck((uint32_t)-1, m_Jump.RegSet); + m_RecompilerOps->CompileInPermLoop(m_Jump.RegSet, m_RecompilerOps->GetCurrentPC()); } } if (TargetSection[0] != TargetSection[1] || TargetSection[0] == NULL) @@ -245,34 +240,16 @@ void CCodeSection::GenerateSectionLinkage() } else if (TargetSection[i] == NULL && JumpInfo[i]->FallThrough) { - if (JumpInfo[i]->LinkLocation != NULL) - { - SetJump32(JumpInfo[i]->LinkLocation, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation = NULL; - if (JumpInfo[i]->LinkLocation2 != NULL) - { - SetJump32(JumpInfo[i]->LinkLocation2, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation2 = NULL; - } - } - CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->ExitReason, true, NULL); + m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1); + m_RecompilerOps->CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->ExitReason, true); JumpInfo[i]->FallThrough = false; } else if (TargetSection[i] != NULL && JumpInfo[i] != NULL) { if (!JumpInfo[i]->FallThrough) { continue; } if (JumpInfo[i]->TargetPC == TargetSection[i]->m_EnterPC) { continue; } - if (JumpInfo[i]->LinkLocation != NULL) - { - SetJump32(JumpInfo[i]->LinkLocation, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation = NULL; - if (JumpInfo[i]->LinkLocation2 != NULL) - { - SetJump32(JumpInfo[i]->LinkLocation2, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation2 = NULL; - } - } - CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->ExitReason, true, NULL); + m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1); + m_RecompilerOps->CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->ExitReason, true); //FreeSection(TargetSection[i],Section); } } @@ -296,56 +273,31 @@ void CCodeSection::GenerateSectionLinkage() if (TargetSection[i]->m_CompiledLocation != NULL) { - char Label[100]; - sprintf(Label, "Section_%d", TargetSection[i]->m_SectionID); JumpInfo[i]->FallThrough = false; - if (JumpInfo[i]->LinkLocation != NULL) - { - SetJump32(JumpInfo[i]->LinkLocation, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation = NULL; - if (JumpInfo[i]->LinkLocation2 != NULL) - { - SetJump32(JumpInfo[i]->LinkLocation2, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation2 = NULL; - } - } - if (JumpInfo[i]->TargetPC <= CompilePC()) + m_RecompilerOps->LinkJump(*JumpInfo[i], TargetSection[i]->m_SectionID); + if (JumpInfo[i]->TargetPC <= m_RecompilerOps->GetCurrentPC()) { if (JumpInfo[i]->PermLoop) { CPU_Message("PermLoop *** 1"); - MoveConstToVariable(JumpInfo[i]->TargetPC, _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - UpdateCounters(JumpInfo[i]->RegSet, false, true); - if (g_SyncSystem) - { - MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - - //JumpInfo[i]->RegSet.BlockCycleCount() -= g_System->CountPerOp(); - Call_Direct(AddressOf(CInterpreterCPU::InPermLoop), "CInterpreterCPU::InPermLoop"); - //JumpInfo[i]->RegSet.BlockCycleCount() += g_System->CountPerOp(); - UpdateCounters(JumpInfo[i]->RegSet, true, true); - CPU_Message("CompileSystemCheck 4"); - CompileSystemCheck((uint32_t)-1, JumpInfo[i]->RegSet); + m_RecompilerOps->CompileInPermLoop(JumpInfo[i]->RegSet, JumpInfo[i]->TargetPC); } else { - UpdateCounters(JumpInfo[i]->RegSet, true, true); + m_RecompilerOps->UpdateCounters(JumpInfo[i]->RegSet, true, true); CPU_Message("CompileSystemCheck 5"); - CompileSystemCheck(JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet); + m_RecompilerOps->CompileSystemCheck(JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet); } } else { - UpdateCounters(JumpInfo[i]->RegSet, false, true); + m_RecompilerOps->UpdateCounters(JumpInfo[i]->RegSet, false, true); } JumpInfo[i]->RegSet.SetBlockCycleCount(0); - m_RegWorkingSet = JumpInfo[i]->RegSet; - SyncRegState(TargetSection[i]->m_RegEnter); - JmpLabel32(Label, 0); - SetJump32((uint32_t *)*g_RecompPos - 1, (uint32_t *)(TargetSection[i]->m_CompiledLocation)); + m_RecompilerOps->SetRegWorkingSet(JumpInfo[i]->RegSet); + m_RecompilerOps->SyncRegState(TargetSection[i]->m_RegEnter); + m_RecompilerOps->JumpToSection(TargetSection[i]); } } @@ -362,18 +314,12 @@ void CCodeSection::GenerateSectionLinkage() if (JumpInfo[i]->PermLoop) { CPU_Message("PermLoop *** 2"); - MoveConstToVariable(JumpInfo[i]->TargetPC, _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - UpdateCounters(JumpInfo[i]->RegSet, false, true); - Call_Direct(AddressOf(CInterpreterCPU::InPermLoop), "CInterpreterCPU::InPermLoop"); - UpdateCounters(JumpInfo[i]->RegSet, true, true); - CPU_Message("CompileSystemCheck 6"); - CompileSystemCheck((uint32_t)-1, JumpInfo[i]->RegSet); + m_RecompilerOps->CompileInPermLoop(JumpInfo[i]->RegSet, JumpInfo[i]->TargetPC); } if (JumpInfo[i]->FallThrough) { JumpInfo[i]->FallThrough = false; - JmpLabel32(JumpInfo[i]->BranchLabel.c_str(), 0); - JumpInfo[i]->LinkLocation = (uint32_t*)(*g_RecompPos - 4); + m_RecompilerOps->JumpToUnknown(JumpInfo[i]); } } } @@ -382,11 +328,11 @@ void CCodeSection::GenerateSectionLinkage() { if (JumpInfo[i]->FallThrough) { - if (JumpInfo[i]->TargetPC < CompilePC()) + if (JumpInfo[i]->TargetPC < m_RecompilerOps->GetCurrentPC()) { - UpdateCounters(JumpInfo[i]->RegSet, true, true); + m_RecompilerOps->UpdateCounters(JumpInfo[i]->RegSet, true, true); CPU_Message("CompileSystemCheck 7"); - CompileSystemCheck(JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet); + m_RecompilerOps->CompileSystemCheck(JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet); } } } @@ -398,8 +344,7 @@ void CCodeSection::GenerateSectionLinkage() if (JumpInfo[i]->FallThrough && !TargetSection[i]->GenerateNativeCode(m_BlockInfo->NextTest())) { JumpInfo[i]->FallThrough = false; - JmpLabel32(JumpInfo[i]->BranchLabel.c_str(), 0); - JumpInfo[i]->LinkLocation = (uint32_t *)(*g_RecompPos - 4); + m_RecompilerOps->JumpToUnknown(JumpInfo[i]); } } @@ -410,14 +355,8 @@ void CCodeSection::GenerateSectionLinkage() if (TargetSection[i] == NULL) { CPU_Message("ExitBlock (from %d):", m_SectionID); - SetJump32(JumpInfo[i]->LinkLocation, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation = NULL; - if (JumpInfo[i]->LinkLocation2 != NULL) - { - SetJump32(JumpInfo[i]->LinkLocation2, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation2 = NULL; - } - CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->ExitReason, true, NULL); + m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1); + m_RecompilerOps->CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->ExitReason, true); continue; } if (JumpInfo[i]->TargetPC != TargetSection[i]->m_EnterPC) @@ -433,258 +372,29 @@ void CCodeSection::GenerateSectionLinkage() stdstr_f Label("Section_%d (from %d):", TargetSection[i]->m_SectionID, m_SectionID); CPU_Message(Label.c_str()); - SetJump32(JumpInfo[i]->LinkLocation, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation = NULL; - if (JumpInfo[i]->LinkLocation2 != NULL) - { - SetJump32(JumpInfo[i]->LinkLocation2, (uint32_t *)*g_RecompPos); - JumpInfo[i]->LinkLocation2 = NULL; - } - m_RegWorkingSet = JumpInfo[i]->RegSet; + m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1); + m_RecompilerOps->SetRegWorkingSet(JumpInfo[i]->RegSet); if (JumpInfo[i]->TargetPC <= JumpInfo[i]->JumpPC) { - UpdateCounters(JumpInfo[i]->RegSet, true, true); + m_RecompilerOps->UpdateCounters(JumpInfo[i]->RegSet, true, true); if (JumpInfo[i]->PermLoop) { CPU_Message("PermLoop *** 3"); - MoveConstToVariable(JumpInfo[i]->TargetPC, _PROGRAM_COUNTER, "PROGRAM_COUNTER"); - Call_Direct(AddressOf(CInterpreterCPU::InPermLoop), "CInterpreterCPU::InPermLoop"); - CPU_Message("CompileSystemCheck 8"); - CompileSystemCheck((uint32_t)-1, JumpInfo[i]->RegSet); + m_RecompilerOps->CompileInPermLoop(JumpInfo[i]->RegSet, JumpInfo[i]->TargetPC); } else { CPU_Message("CompileSystemCheck 9"); - CompileSystemCheck(JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet); + m_RecompilerOps->CompileSystemCheck(JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet); } } else { - UpdateCounters(m_RegWorkingSet, false, true); + m_RecompilerOps->UpdateCounters(m_RecompilerOps->GetRegWorkingSet(), false, true); } - m_RegWorkingSet = JumpInfo[i]->RegSet; - SyncRegState(TargetSection[i]->m_RegEnter); - JmpLabel32(Label.c_str(), 0); - SetJump32((uint32_t *)*g_RecompPos - 1, (uint32_t *)(TargetSection[i]->m_CompiledLocation)); - } - } -} - -void CCodeSection::SyncRegState(const CRegInfo & SyncTo) -{ - ResetX86Protection(); - - bool changed = false; - UnMap_AllFPRs(); - if (m_RegWorkingSet.GetRoundingModel() != SyncTo.GetRoundingModel()) { m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); } - x86Reg MemStackReg = Get_MemoryStack(); - x86Reg TargetStackReg = SyncTo.Get_MemoryStack(); - - //CPU_Message("MemoryStack for Original State = %s",MemStackReg > 0?x86_Name(MemStackReg):"Not Mapped"); - if (MemStackReg != TargetStackReg) - { - if (TargetStackReg == x86_Unknown) - { - UnMap_X86reg(MemStackReg); - } - else if (MemStackReg == x86_Unknown) - { - UnMap_X86reg(TargetStackReg); - CPU_Message(" regcache: allocate %s as Memory Stack", x86_Name(TargetStackReg)); - m_RegWorkingSet.SetX86Mapped(TargetStackReg, CRegInfo::Stack_Mapped); - MoveVariableToX86reg(&g_Recompiler->MemoryStackPos(), "MemoryStack", TargetStackReg); - } - else - { - UnMap_X86reg(TargetStackReg); - CPU_Message(" regcache: change allocation of Memory Stack from %s to %s", x86_Name(MemStackReg), x86_Name(TargetStackReg)); - m_RegWorkingSet.SetX86Mapped(TargetStackReg, CRegInfo::Stack_Mapped); - m_RegWorkingSet.SetX86Mapped(MemStackReg, CRegInfo::NotMapped); - MoveX86RegToX86Reg(MemStackReg, TargetStackReg); - } - } - - for (int i = 1; i < 32; i++) - { - if (GetMipsRegState(i) == SyncTo.GetMipsRegState(i) || - (g_System->b32BitCore() && GetMipsRegState(i) == CRegInfo::STATE_MAPPED_32_ZERO && SyncTo.GetMipsRegState(i) == CRegInfo::STATE_MAPPED_32_SIGN) || - (g_System->b32BitCore() && GetMipsRegState(i) == CRegInfo::STATE_MAPPED_32_SIGN && SyncTo.GetMipsRegState(i) == CRegInfo::STATE_MAPPED_32_ZERO)) - { - switch (GetMipsRegState(i)) { - case CRegInfo::STATE_UNKNOWN: continue; - case CRegInfo::STATE_MAPPED_64: - if (GetMipsRegMapHi(i) == SyncTo.GetMipsRegMapHi(i) && - GetMipsRegMapLo(i) == SyncTo.GetMipsRegMapLo(i)) - { - continue; - } - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - case CRegInfo::STATE_MAPPED_32_SIGN: - if (GetMipsRegMapLo(i) == SyncTo.GetMipsRegMapLo(i)) - { - continue; - } - break; - case CRegInfo::STATE_CONST_64: - if (GetMipsReg(i) != SyncTo.GetMipsReg(i)) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - continue; - case CRegInfo::STATE_CONST_32_SIGN: - if (GetMipsRegLo(i) != SyncTo.GetMipsRegLo(i)) - { - CPU_Message("Value of const is different Reg %d (%s) Value: 0x%08X to 0x%08X", i, CRegName::GPR[i], GetMipsRegLo(i), SyncTo.GetMipsRegLo(i)); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - continue; - default: - CPU_Message("Unhandled Reg state %d\nin SyncRegState", GetMipsRegState(i)); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - changed = true; - - switch (SyncTo.GetMipsRegState(i)) - { - case CRegInfo::STATE_UNKNOWN: UnMap_GPR(i, true); break; - case CRegInfo::STATE_MAPPED_64: - { - x86Reg Reg = SyncTo.GetMipsRegMapLo(i); - x86Reg x86RegHi = SyncTo.GetMipsRegMapHi(i); - UnMap_X86reg(Reg); - UnMap_X86reg(x86RegHi); - switch (GetMipsRegState(i)) - { - case CRegInfo::STATE_UNKNOWN: - MoveVariableToX86reg(&_GPR[i].UW[0], CRegName::GPR_Lo[i], Reg); - MoveVariableToX86reg(&_GPR[i].UW[1], CRegName::GPR_Hi[i], x86RegHi); - break; - case CRegInfo::STATE_MAPPED_64: - MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); - MoveX86RegToX86Reg(GetMipsRegMapHi(i), x86RegHi); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapHi(i), CRegInfo::NotMapped); - break; - case CRegInfo::STATE_MAPPED_32_SIGN: - MoveX86RegToX86Reg(GetMipsRegMapLo(i), x86RegHi); - ShiftRightSignImmed(x86RegHi, 31); - MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - XorX86RegToX86Reg(x86RegHi, x86RegHi); - MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); - break; - case CRegInfo::STATE_CONST_64: - MoveConstToX86reg(GetMipsRegHi(i), x86RegHi); - MoveConstToX86reg(GetMipsRegLo(i), Reg); - break; - case CRegInfo::STATE_CONST_32_SIGN: - MoveConstToX86reg(GetMipsRegLo_S(i) >> 31, x86RegHi); - MoveConstToX86reg(GetMipsRegLo(i), Reg); - break; - default: - CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_64\n%d", GetMipsRegState(i)); - g_Notify->BreakPoint(__FILE__, __LINE__); - continue; - } - m_RegWorkingSet.SetMipsRegMapLo(i, Reg); - m_RegWorkingSet.SetMipsRegMapHi(i, x86RegHi); - m_RegWorkingSet.SetMipsRegState(i, CRegInfo::STATE_MAPPED_64); - m_RegWorkingSet.SetX86Mapped(Reg, CRegInfo::GPR_Mapped); - m_RegWorkingSet.SetX86Mapped(x86RegHi, CRegInfo::GPR_Mapped); - m_RegWorkingSet.SetX86MapOrder(Reg, 1); - m_RegWorkingSet.SetX86MapOrder(x86RegHi, 1); - } - break; - case CRegInfo::STATE_MAPPED_32_SIGN: - { - x86Reg Reg = SyncTo.GetMipsRegMapLo(i); - UnMap_X86reg(Reg); - switch (GetMipsRegState(i)) - { - case CRegInfo::STATE_UNKNOWN: MoveVariableToX86reg(&_GPR[i].UW[0], CRegName::GPR_Lo[i], Reg); break; - case CRegInfo::STATE_CONST_32_SIGN: MoveConstToX86reg(GetMipsRegLo(i), Reg); break; - case CRegInfo::STATE_MAPPED_32_SIGN: - MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - if (GetMipsRegMapLo(i) != Reg) - { - MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); - } - break; - case CRegInfo::STATE_MAPPED_64: - MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapHi(i), CRegInfo::NotMapped); - break; - case CRegInfo::STATE_CONST_64: - CPU_Message("hi %X\nLo %X", GetMipsRegHi(i), GetMipsRegLo(i)); - default: - CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_SIGN\n%d", GetMipsRegState(i)); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - m_RegWorkingSet.SetMipsRegMapLo(i, Reg); - m_RegWorkingSet.SetMipsRegState(i, CRegInfo::STATE_MAPPED_32_SIGN); - m_RegWorkingSet.SetX86Mapped(Reg, CRegInfo::GPR_Mapped); - m_RegWorkingSet.SetX86MapOrder(Reg, 1); - } - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - { - x86Reg Reg = SyncTo.GetMipsRegMapLo(i); - UnMap_X86reg(Reg); - switch (GetMipsRegState(i)) - { - case CRegInfo::STATE_MAPPED_64: - case CRegInfo::STATE_UNKNOWN: - MoveVariableToX86reg(&_GPR[i].UW[0], CRegName::GPR_Lo[i], Reg); - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); - break; - case CRegInfo::STATE_MAPPED_32_SIGN: - if (g_System->b32BitCore()) - { - MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); - m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); - } - else - { - CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d", GetMipsRegState(i)); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - break; - case CRegInfo::STATE_CONST_32_SIGN: - if (!g_System->b32BitCore() && GetMipsRegLo_S(i) < 0) - { - CPU_Message("Sign Problems in SyncRegState\nSTATE_MAPPED_32_ZERO"); - CPU_Message("%s: %X", CRegName::GPR[i], GetMipsRegLo_S(i)); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - MoveConstToX86reg(GetMipsRegLo(i), Reg); - break; - default: - CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d", GetMipsRegState(i)); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - m_RegWorkingSet.SetMipsRegMapLo(i, Reg); - m_RegWorkingSet.SetMipsRegState(i, SyncTo.GetMipsRegState(i)); - m_RegWorkingSet.SetX86Mapped(Reg, CRegInfo::GPR_Mapped); - m_RegWorkingSet.SetX86MapOrder(Reg, 1); - } - break; - default: - CPU_Message("%d - %d reg: %s (%d)", SyncTo.GetMipsRegState(i), GetMipsRegState(i), CRegName::GPR[i], i); - g_Notify->BreakPoint(__FILE__, __LINE__); - changed = false; + m_RecompilerOps->SetRegWorkingSet(JumpInfo[i]->RegSet); + m_RecompilerOps->SyncRegState(TargetSection[i]->m_RegEnter); + m_RecompilerOps->JumpToSection(TargetSection[i]); } } } @@ -709,16 +419,6 @@ void CCodeSection::SetContinueAddress(uint32_t JumpPC, uint32_t TargetPC) m_Cont.BranchLabel.Format("0x%08X", TargetPC); } -void CCodeSection::CompileCop1Test() -{ - if (m_RegWorkingSet.FpuBeenUsed()) - return; - - TestVariable(STATUS_CU1, &g_Reg->STATUS_REGISTER, "STATUS_REGISTER"); - CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::COP1_Unuseable, false, JeLabel32); - m_RegWorkingSet.FpuBeenUsed() = true; -} - bool CCodeSection::ParentContinue() { if (m_ParentSection.size() > 0) @@ -730,7 +430,8 @@ bool CCodeSection::ParentContinue() if (IsAllParentLoops(Parent, true, m_BlockInfo->NextTest())) { continue; } return false; } - if (!InheritParentInfo()) + m_RecompilerOps->SetCurrentSection(this); + if (!m_RecompilerOps->InheritParentInfo()) { return false; } @@ -738,16 +439,6 @@ bool CCodeSection::ParentContinue() return true; } -/*int TestValue = 0; -void TestFunc() -{ -TestValue += 1; -if (TestValue >= 4) -{ -g_Notify->BreakPoint(__FILE__, __LINE__); -} -}*/ - bool CCodeSection::GenerateNativeCode(uint32_t Test) { if (this == NULL) { return false; } @@ -769,287 +460,171 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) return false; } m_CompiledLocation = *g_RecompPos; - m_RegWorkingSet = m_RegEnter; - m_CompilePC = m_EnterPC; - m_NextInstruction = m_DelaySlot ? JUMP : NORMAL; - m_Section = this; + m_RecompilerOps->SetRegWorkingSet(m_RegEnter); + m_RecompilerOps->SetCurrentPC(m_EnterPC); + m_RecompilerOps->SetNextStepType(m_DelaySlot ? JUMP : NORMAL); - if (m_CompilePC < m_BlockInfo->VAddrFirst()) + if (m_RecompilerOps->GetCurrentPC() < m_BlockInfo->VAddrFirst()) { - m_BlockInfo->SetVAddrFirst(m_CompilePC); + m_BlockInfo->SetVAddrFirst(m_RecompilerOps->GetCurrentPC()); } uint32_t ContinueSectionPC = m_ContinueSection ? m_ContinueSection->m_EnterPC : (uint32_t)-1; - + const OPCODE & Opcode = m_RecompilerOps->GetOpcode(); do { - __except_try() + if (m_RecompilerOps->GetCurrentPC() > m_BlockInfo->VAddrLast()) { - if (!g_MMU->LW_VAddr(m_CompilePC, m_Opcode.Hex)) - { - g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD)); - } - } - __except_catch() - { - g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION)); + m_BlockInfo->SetVAddrLast(m_RecompilerOps->GetCurrentPC()); } + m_RecompilerOps->PreCompileOpcode(); - if (m_CompilePC > m_BlockInfo->VAddrLast()) - { - m_BlockInfo->SetVAddrLast(m_CompilePC); - } - /*if (m_CompilePC == 0x803245C4) - { - X86BreakPoint(__FILEW__,__LINE__); - //m_RegWorkingSet.UnMap_AllFPRs(); - }*/ - - /*if (m_CompilePC >= 0x80000000 && m_CompilePC <= 0x80400000 && m_NextInstruction == NORMAL) - { - m_RegWorkingSet.WriteBackRegisters(); - UpdateCounters(m_RegWorkingSet,false,true); - MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); - if (g_SyncSystem) { - MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - }*/ - - /*if ((m_CompilePC == 0x8031C0E4 || m_CompilePC == 0x8031C118 || - m_CompilePC == 0x8031CD88 || m_CompilePC == 0x8031CE24 || - m_CompilePC == 0x8031CE30 || m_CompilePC == 0x8031CE40) && m_NextInstruction == NORMAL) - { - m_RegWorkingSet.WriteBackRegisters(); - UpdateCounters(m_RegWorkingSet,false,true); - MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); - if (g_SyncSystem) { - MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - }*/ - - /*if (m_CompilePC == 0x801C1B88) - { - BeforeCallDirect(m_RegWorkingSet); - Call_Direct(AddressOf(TestFunc), "TestFunc"); - AfterCallDirect(m_RegWorkingSet); - }*/ - - /*if (m_CompilePC >= 0x801C1AF8 && m_CompilePC <= 0x801C1C00 && m_NextInstruction == NORMAL) - { - UpdateCounters(m_RegWorkingSet,false,true); - MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); - if (g_SyncSystem) { - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystemPC), "CN64System::SyncSystemPC"); - AfterCallDirect(m_RegWorkingSet); - } - }*/ - - /*if ((m_CompilePC == 0x80263900) && m_NextInstruction == NORMAL) - { - X86BreakPoint(__FILEW__,__LINE__); - }*/ - - /*if ((m_CompilePC >= 0x80325D80 && m_CompilePC <= 0x80325DF0) && m_NextInstruction == NORMAL) - { - m_RegWorkingSet.WriteBackRegisters(); - UpdateCounters(m_RegWorkingSet,false,true); - MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); - if (g_SyncSystem) { - MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - }*/ - /*if ((m_CompilePC == 0x80324E14) && m_NextInstruction == NORMAL) - { - X86BreakPoint(__FILEW__,__LINE__); - }*/ - - /*if (m_CompilePC == 0x80324E18 && m_NextInstruction == NORMAL) - { - m_RegWorkingSet.WriteBackRegisters(); - UpdateCounters(m_RegWorkingSet,false,true); - MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); - if (g_SyncSystem) { - MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - }*/ - /*if (m_CompilePC >= 0x80324E00 && m_CompilePC <= 0x80324E18 && m_NextInstruction == NORMAL) - { - m_RegWorkingSet.WriteBackRegisters(); - UpdateCounters(m_RegWorkingSet,false,true); - MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); - if (g_SyncSystem) { - MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); - Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); - } - }*/ - /* if (m_CompilePC == 0x803245CC && m_NextInstruction == NORMAL) - { - //m_RegWorkingSet.UnMap_AllFPRs(); - g_Notify->BreakPoint(__FILE__, __LINE__); - //X86HardBreakPoint(); - //X86BreakPoint(__FILEW__,__LINE__); - //m_RegWorkingSet.UnMap_AllFPRs(); - }*/ - /*if (m_CompilePC >= 0x80179DC4 && m_CompilePC <= 0x80179DF0 && m_NextInstruction == NORMAL) - { - m_RegWorkingSet.UnMap_AllFPRs(); - }*/ - - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); - m_RegWorkingSet.ResetX86Protection(); - - switch (m_Opcode.op) + switch (Opcode.op) { case R4300i_SPECIAL: - switch (m_Opcode.funct) + switch (Opcode.funct) { - case R4300i_SPECIAL_SLL: SPECIAL_SLL(); break; - case R4300i_SPECIAL_SRL: SPECIAL_SRL(); break; - case R4300i_SPECIAL_SRA: SPECIAL_SRA(); break; - case R4300i_SPECIAL_SLLV: SPECIAL_SLLV(); break; - case R4300i_SPECIAL_SRLV: SPECIAL_SRLV(); break; - case R4300i_SPECIAL_SRAV: SPECIAL_SRAV(); break; - case R4300i_SPECIAL_JR: SPECIAL_JR(); break; - case R4300i_SPECIAL_JALR: SPECIAL_JALR(); break; - case R4300i_SPECIAL_MFLO: SPECIAL_MFLO(); break; - case R4300i_SPECIAL_SYSCALL: SPECIAL_SYSCALL(); break; - case R4300i_SPECIAL_MTLO: SPECIAL_MTLO(); break; - case R4300i_SPECIAL_MFHI: SPECIAL_MFHI(); break; - case R4300i_SPECIAL_MTHI: SPECIAL_MTHI(); break; - case R4300i_SPECIAL_DSLLV: SPECIAL_DSLLV(); break; - case R4300i_SPECIAL_DSRLV: SPECIAL_DSRLV(); break; - case R4300i_SPECIAL_DSRAV: SPECIAL_DSRAV(); break; - case R4300i_SPECIAL_MULT: SPECIAL_MULT(); break; - case R4300i_SPECIAL_DIV: SPECIAL_DIV(); break; - case R4300i_SPECIAL_DIVU: SPECIAL_DIVU(); break; - case R4300i_SPECIAL_MULTU: SPECIAL_MULTU(); break; - case R4300i_SPECIAL_DMULT: SPECIAL_DMULT(); break; - case R4300i_SPECIAL_DMULTU: SPECIAL_DMULTU(); break; - case R4300i_SPECIAL_DDIV: SPECIAL_DDIV(); break; - case R4300i_SPECIAL_DDIVU: SPECIAL_DDIVU(); break; - case R4300i_SPECIAL_ADD: SPECIAL_ADD(); break; - case R4300i_SPECIAL_ADDU: SPECIAL_ADDU(); break; - case R4300i_SPECIAL_SUB: SPECIAL_SUB(); break; - case R4300i_SPECIAL_SUBU: SPECIAL_SUBU(); break; - case R4300i_SPECIAL_AND: SPECIAL_AND(); break; - case R4300i_SPECIAL_OR: SPECIAL_OR(); break; - case R4300i_SPECIAL_XOR: SPECIAL_XOR(); break; - case R4300i_SPECIAL_NOR: SPECIAL_NOR(); break; - case R4300i_SPECIAL_SLT: SPECIAL_SLT(); break; - case R4300i_SPECIAL_SLTU: SPECIAL_SLTU(); break; - case R4300i_SPECIAL_DADD: SPECIAL_DADD(); break; - case R4300i_SPECIAL_DADDU: SPECIAL_DADDU(); break; - case R4300i_SPECIAL_DSUB: SPECIAL_DSUB(); break; - case R4300i_SPECIAL_DSUBU: SPECIAL_DSUBU(); break; - case R4300i_SPECIAL_DSLL: SPECIAL_DSLL(); break; - case R4300i_SPECIAL_DSRL: SPECIAL_DSRL(); break; - case R4300i_SPECIAL_DSRA: SPECIAL_DSRA(); break; - case R4300i_SPECIAL_DSLL32: SPECIAL_DSLL32(); break; - case R4300i_SPECIAL_DSRL32: SPECIAL_DSRL32(); break; - case R4300i_SPECIAL_DSRA32: SPECIAL_DSRA32(); break; + case R4300i_SPECIAL_SLL: m_RecompilerOps->SPECIAL_SLL(); break; + case R4300i_SPECIAL_SRL: m_RecompilerOps->SPECIAL_SRL(); break; + case R4300i_SPECIAL_SRA: m_RecompilerOps->SPECIAL_SRA(); break; + case R4300i_SPECIAL_SLLV: m_RecompilerOps->SPECIAL_SLLV(); break; + case R4300i_SPECIAL_SRLV: m_RecompilerOps->SPECIAL_SRLV(); break; + case R4300i_SPECIAL_SRAV: m_RecompilerOps->SPECIAL_SRAV(); break; + case R4300i_SPECIAL_JR: m_RecompilerOps->SPECIAL_JR(); break; + case R4300i_SPECIAL_JALR: m_RecompilerOps->SPECIAL_JALR(); break; + case R4300i_SPECIAL_MFLO: m_RecompilerOps->SPECIAL_MFLO(); break; + case R4300i_SPECIAL_SYSCALL: m_RecompilerOps->SPECIAL_SYSCALL(); break; + case R4300i_SPECIAL_MTLO: m_RecompilerOps->SPECIAL_MTLO(); break; + case R4300i_SPECIAL_MFHI: m_RecompilerOps->SPECIAL_MFHI(); break; + case R4300i_SPECIAL_MTHI: m_RecompilerOps->SPECIAL_MTHI(); break; + case R4300i_SPECIAL_DSLLV: m_RecompilerOps->SPECIAL_DSLLV(); break; + case R4300i_SPECIAL_DSRLV: m_RecompilerOps->SPECIAL_DSRLV(); break; + case R4300i_SPECIAL_DSRAV: m_RecompilerOps->SPECIAL_DSRAV(); break; + case R4300i_SPECIAL_MULT: m_RecompilerOps->SPECIAL_MULT(); break; + case R4300i_SPECIAL_DIV: m_RecompilerOps->SPECIAL_DIV(); break; + case R4300i_SPECIAL_DIVU: m_RecompilerOps->SPECIAL_DIVU(); break; + case R4300i_SPECIAL_MULTU: m_RecompilerOps->SPECIAL_MULTU(); break; + case R4300i_SPECIAL_DMULT: m_RecompilerOps->SPECIAL_DMULT(); break; + case R4300i_SPECIAL_DMULTU: m_RecompilerOps->SPECIAL_DMULTU(); break; + case R4300i_SPECIAL_DDIV: m_RecompilerOps->SPECIAL_DDIV(); break; + case R4300i_SPECIAL_DDIVU: m_RecompilerOps->SPECIAL_DDIVU(); break; + case R4300i_SPECIAL_ADD: m_RecompilerOps->SPECIAL_ADD(); break; + case R4300i_SPECIAL_ADDU: m_RecompilerOps->SPECIAL_ADDU(); break; + case R4300i_SPECIAL_SUB: m_RecompilerOps->SPECIAL_SUB(); break; + case R4300i_SPECIAL_SUBU: m_RecompilerOps->SPECIAL_SUBU(); break; + case R4300i_SPECIAL_AND: m_RecompilerOps->SPECIAL_AND(); break; + case R4300i_SPECIAL_OR: m_RecompilerOps->SPECIAL_OR(); break; + case R4300i_SPECIAL_XOR: m_RecompilerOps->SPECIAL_XOR(); break; + case R4300i_SPECIAL_NOR: m_RecompilerOps->SPECIAL_NOR(); break; + case R4300i_SPECIAL_SLT: m_RecompilerOps->SPECIAL_SLT(); break; + case R4300i_SPECIAL_SLTU: m_RecompilerOps->SPECIAL_SLTU(); break; + case R4300i_SPECIAL_DADD: m_RecompilerOps->SPECIAL_DADD(); break; + case R4300i_SPECIAL_DADDU: m_RecompilerOps->SPECIAL_DADDU(); break; + case R4300i_SPECIAL_DSUB: m_RecompilerOps->SPECIAL_DSUB(); break; + case R4300i_SPECIAL_DSUBU: m_RecompilerOps->SPECIAL_DSUBU(); break; + case R4300i_SPECIAL_DSLL: m_RecompilerOps->SPECIAL_DSLL(); break; + case R4300i_SPECIAL_DSRL: m_RecompilerOps->SPECIAL_DSRL(); break; + case R4300i_SPECIAL_DSRA: m_RecompilerOps->SPECIAL_DSRA(); break; + case R4300i_SPECIAL_DSLL32: m_RecompilerOps->SPECIAL_DSLL32(); break; + case R4300i_SPECIAL_DSRL32: m_RecompilerOps->SPECIAL_DSRL32(); break; + case R4300i_SPECIAL_DSRA32: m_RecompilerOps->SPECIAL_DSRA32(); break; default: - UnknownOpcode(); break; + m_RecompilerOps->UnknownOpcode(); break; } break; case R4300i_REGIMM: - switch (m_Opcode.rt) + switch (Opcode.rt) { - case R4300i_REGIMM_BLTZ:Compile_Branch(CRecompilerOps::CompareTypeBLTZ, BranchTypeRs, false); break; - case R4300i_REGIMM_BGEZ:Compile_Branch(CRecompilerOps::CompareTypeBGEZ, BranchTypeRs, false); break; - case R4300i_REGIMM_BLTZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBLTZ, false); break; - case R4300i_REGIMM_BGEZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBGEZ, false); break; - case R4300i_REGIMM_BLTZAL:Compile_Branch(CRecompilerOps::CompareTypeBLTZ, BranchTypeRs, true); break; - case R4300i_REGIMM_BGEZAL:Compile_Branch(CRecompilerOps::CompareTypeBGEZ, BranchTypeRs, true); break; + case R4300i_REGIMM_BLTZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLTZ, CRecompilerOps::BranchTypeRs, false); break; + case R4300i_REGIMM_BGEZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGEZ, CRecompilerOps::BranchTypeRs, false); break; + case R4300i_REGIMM_BLTZL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBLTZ, false); break; + case R4300i_REGIMM_BGEZL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBGEZ, false); break; + case R4300i_REGIMM_BLTZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLTZ, CRecompilerOps::BranchTypeRs, true); break; + case R4300i_REGIMM_BGEZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGEZ, CRecompilerOps::BranchTypeRs, true); break; default: - UnknownOpcode(); break; + m_RecompilerOps->UnknownOpcode(); break; } break; - case R4300i_BEQ: Compile_Branch(CRecompilerOps::CompareTypeBEQ, BranchTypeRsRt, false); break; - case R4300i_BNE: Compile_Branch(CRecompilerOps::CompareTypeBNE, BranchTypeRsRt, false); break; - case R4300i_BGTZ:Compile_Branch(CRecompilerOps::CompareTypeBGTZ, BranchTypeRs, false); break; - case R4300i_BLEZ:Compile_Branch(CRecompilerOps::CompareTypeBLEZ, BranchTypeRs, false); break; - case R4300i_J: J(); break; - case R4300i_JAL: JAL(); break; - case R4300i_ADDI: ADDI(); break; - case R4300i_ADDIU: ADDIU(); break; - case R4300i_SLTI: SLTI(); break; - case R4300i_SLTIU: SLTIU(); break; - case R4300i_ANDI: ANDI(); break; - case R4300i_ORI: ORI(); break; - case R4300i_XORI: XORI(); break; - case R4300i_LUI: LUI(); break; + case R4300i_BEQ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBEQ, CRecompilerOps::BranchTypeRsRt, false); break; + case R4300i_BNE: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBNE, CRecompilerOps::BranchTypeRsRt, false); break; + case R4300i_BGTZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGTZ, CRecompilerOps::BranchTypeRs, false); break; + case R4300i_BLEZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLEZ, CRecompilerOps::BranchTypeRs, false); break; + case R4300i_J: m_RecompilerOps->J(); break; + case R4300i_JAL: m_RecompilerOps->JAL(); break; + case R4300i_ADDI: m_RecompilerOps->ADDI(); break; + case R4300i_ADDIU: m_RecompilerOps->ADDIU(); break; + case R4300i_SLTI: m_RecompilerOps->SLTI(); break; + case R4300i_SLTIU: m_RecompilerOps->SLTIU(); break; + case R4300i_ANDI: m_RecompilerOps->ANDI(); break; + case R4300i_ORI: m_RecompilerOps->ORI(); break; + case R4300i_XORI: m_RecompilerOps->XORI(); break; + case R4300i_LUI: m_RecompilerOps->LUI(); break; case R4300i_CP0: - switch (m_Opcode.rs) + switch (Opcode.rs) { - case R4300i_COP0_MF: COP0_MF(); break; - case R4300i_COP0_MT: COP0_MT(); break; + case R4300i_COP0_MF: m_RecompilerOps->COP0_MF(); break; + case R4300i_COP0_MT: m_RecompilerOps->COP0_MT(); break; default: - if ((m_Opcode.rs & 0x10) != 0) + if ((Opcode.rs & 0x10) != 0) { - switch (m_Opcode.funct) + switch (Opcode.funct) { - case R4300i_COP0_CO_TLBR: COP0_CO_TLBR(); break; - case R4300i_COP0_CO_TLBWI: COP0_CO_TLBWI(); break; - case R4300i_COP0_CO_TLBWR: COP0_CO_TLBWR(); break; - case R4300i_COP0_CO_TLBP: COP0_CO_TLBP(); break; - case R4300i_COP0_CO_ERET: COP0_CO_ERET(); break; - default: UnknownOpcode(); break; + case R4300i_COP0_CO_TLBR: m_RecompilerOps->COP0_CO_TLBR(); break; + case R4300i_COP0_CO_TLBWI: m_RecompilerOps->COP0_CO_TLBWI(); break; + case R4300i_COP0_CO_TLBWR: m_RecompilerOps->COP0_CO_TLBWR(); break; + case R4300i_COP0_CO_TLBP: m_RecompilerOps->COP0_CO_TLBP(); break; + case R4300i_COP0_CO_ERET: m_RecompilerOps->COP0_CO_ERET(); break; + default: m_RecompilerOps->UnknownOpcode(); break; } } else { - UnknownOpcode(); + m_RecompilerOps->UnknownOpcode(); } } break; case R4300i_CP1: - switch (m_Opcode.rs) + switch (Opcode.rs) { - case R4300i_COP1_MF: COP1_MF(); break; - case R4300i_COP1_DMF: COP1_DMF(); break; - case R4300i_COP1_CF: COP1_CF(); break; - case R4300i_COP1_MT: COP1_MT(); break; - case R4300i_COP1_DMT: COP1_DMT(); break; - case R4300i_COP1_CT: COP1_CT(); break; + case R4300i_COP1_MF: m_RecompilerOps->COP1_MF(); break; + case R4300i_COP1_DMF: m_RecompilerOps->COP1_DMF(); break; + case R4300i_COP1_CF: m_RecompilerOps->COP1_CF(); break; + case R4300i_COP1_MT: m_RecompilerOps->COP1_MT(); break; + case R4300i_COP1_DMT: m_RecompilerOps->COP1_DMT(); break; + case R4300i_COP1_CT: m_RecompilerOps->COP1_CT(); break; case R4300i_COP1_BC: - switch (m_Opcode.ft) + switch (Opcode.ft) { - case R4300i_COP1_BC_BCF: Compile_Branch(CRecompilerOps::CompareTypeCOP1BCF, BranchTypeCop1, false); break; - case R4300i_COP1_BC_BCT: Compile_Branch(CRecompilerOps::CompareTypeCOP1BCT, BranchTypeCop1, false); break; - case R4300i_COP1_BC_BCFL: Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCF, false); break; - case R4300i_COP1_BC_BCTL: Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCT, false); break; + case R4300i_COP1_BC_BCF: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeCOP1BCF, CRecompilerOps::BranchTypeCop1, false); break; + case R4300i_COP1_BC_BCT: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeCOP1BCT, CRecompilerOps::BranchTypeCop1, false); break; + case R4300i_COP1_BC_BCFL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCF, false); break; + case R4300i_COP1_BC_BCTL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCT, false); break; default: - UnknownOpcode(); break; + m_RecompilerOps->UnknownOpcode(); break; } break; case R4300i_COP1_S: - switch (m_Opcode.funct) + switch (Opcode.funct) { - case R4300i_COP1_FUNCT_ADD: COP1_S_ADD(); break; - case R4300i_COP1_FUNCT_SUB: COP1_S_SUB(); break; - case R4300i_COP1_FUNCT_MUL: COP1_S_MUL(); break; - case R4300i_COP1_FUNCT_DIV: COP1_S_DIV(); break; - case R4300i_COP1_FUNCT_ABS: COP1_S_ABS(); break; - case R4300i_COP1_FUNCT_NEG: COP1_S_NEG(); break; - case R4300i_COP1_FUNCT_SQRT: COP1_S_SQRT(); break; - case R4300i_COP1_FUNCT_MOV: COP1_S_MOV(); break; - case R4300i_COP1_FUNCT_ROUND_L: COP1_S_ROUND_L(); break; - case R4300i_COP1_FUNCT_TRUNC_L: COP1_S_TRUNC_L(); break; - case R4300i_COP1_FUNCT_CEIL_L: COP1_S_CEIL_L(); break; //added by Witten - case R4300i_COP1_FUNCT_FLOOR_L: COP1_S_FLOOR_L(); break; //added by Witten - case R4300i_COP1_FUNCT_ROUND_W: COP1_S_ROUND_W(); break; - case R4300i_COP1_FUNCT_TRUNC_W: COP1_S_TRUNC_W(); break; - case R4300i_COP1_FUNCT_CEIL_W: COP1_S_CEIL_W(); break; //added by Witten - case R4300i_COP1_FUNCT_FLOOR_W: COP1_S_FLOOR_W(); break; - case R4300i_COP1_FUNCT_CVT_D: COP1_S_CVT_D(); break; - case R4300i_COP1_FUNCT_CVT_W: COP1_S_CVT_W(); break; - case R4300i_COP1_FUNCT_CVT_L: COP1_S_CVT_L(); break; + case R4300i_COP1_FUNCT_ADD: m_RecompilerOps->COP1_S_ADD(); break; + case R4300i_COP1_FUNCT_SUB: m_RecompilerOps->COP1_S_SUB(); break; + case R4300i_COP1_FUNCT_MUL: m_RecompilerOps->COP1_S_MUL(); break; + case R4300i_COP1_FUNCT_DIV: m_RecompilerOps->COP1_S_DIV(); break; + case R4300i_COP1_FUNCT_ABS: m_RecompilerOps->COP1_S_ABS(); break; + case R4300i_COP1_FUNCT_NEG: m_RecompilerOps->COP1_S_NEG(); break; + case R4300i_COP1_FUNCT_SQRT: m_RecompilerOps->COP1_S_SQRT(); break; + case R4300i_COP1_FUNCT_MOV: m_RecompilerOps->COP1_S_MOV(); break; + case R4300i_COP1_FUNCT_ROUND_L: m_RecompilerOps->COP1_S_ROUND_L(); break; + case R4300i_COP1_FUNCT_TRUNC_L: m_RecompilerOps->COP1_S_TRUNC_L(); break; + case R4300i_COP1_FUNCT_CEIL_L: m_RecompilerOps->COP1_S_CEIL_L(); break; + case R4300i_COP1_FUNCT_FLOOR_L: m_RecompilerOps->COP1_S_FLOOR_L(); break; + case R4300i_COP1_FUNCT_ROUND_W: m_RecompilerOps->COP1_S_ROUND_W(); break; + case R4300i_COP1_FUNCT_TRUNC_W: m_RecompilerOps->COP1_S_TRUNC_W(); break; + case R4300i_COP1_FUNCT_CEIL_W: m_RecompilerOps->COP1_S_CEIL_W(); break; + case R4300i_COP1_FUNCT_FLOOR_W: m_RecompilerOps->COP1_S_FLOOR_W(); break; + case R4300i_COP1_FUNCT_CVT_D: m_RecompilerOps->COP1_S_CVT_D(); break; + case R4300i_COP1_FUNCT_CVT_W: m_RecompilerOps->COP1_S_CVT_W(); break; + case R4300i_COP1_FUNCT_CVT_L: m_RecompilerOps->COP1_S_CVT_L(); break; case R4300i_COP1_FUNCT_C_F: case R4300i_COP1_FUNCT_C_UN: case R4300i_COP1_FUNCT_C_EQ: case R4300i_COP1_FUNCT_C_UEQ: case R4300i_COP1_FUNCT_C_OLT: case R4300i_COP1_FUNCT_C_ULT: @@ -1058,33 +633,33 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) case R4300i_COP1_FUNCT_C_SEQ: case R4300i_COP1_FUNCT_C_NGL: case R4300i_COP1_FUNCT_C_LT: case R4300i_COP1_FUNCT_C_NGE: case R4300i_COP1_FUNCT_C_LE: case R4300i_COP1_FUNCT_C_NGT: - COP1_S_CMP(); break; + m_RecompilerOps->COP1_S_CMP(); break; default: - UnknownOpcode(); break; + m_RecompilerOps->UnknownOpcode(); break; } break; case R4300i_COP1_D: - switch (m_Opcode.funct) + switch (Opcode.funct) { - case R4300i_COP1_FUNCT_ADD: COP1_D_ADD(); break; - case R4300i_COP1_FUNCT_SUB: COP1_D_SUB(); break; - case R4300i_COP1_FUNCT_MUL: COP1_D_MUL(); break; - case R4300i_COP1_FUNCT_DIV: COP1_D_DIV(); break; - case R4300i_COP1_FUNCT_ABS: COP1_D_ABS(); break; - case R4300i_COP1_FUNCT_NEG: COP1_D_NEG(); break; - case R4300i_COP1_FUNCT_SQRT: COP1_D_SQRT(); break; - case R4300i_COP1_FUNCT_MOV: COP1_D_MOV(); break; - case R4300i_COP1_FUNCT_ROUND_L: COP1_D_ROUND_L(); break; - case R4300i_COP1_FUNCT_TRUNC_L: COP1_D_TRUNC_L(); break; //added by Witten - case R4300i_COP1_FUNCT_CEIL_L: COP1_D_CEIL_L(); break; //added by Witten - case R4300i_COP1_FUNCT_FLOOR_L: COP1_D_FLOOR_L(); break; //added by Witten - case R4300i_COP1_FUNCT_ROUND_W: COP1_D_ROUND_W(); break; - case R4300i_COP1_FUNCT_TRUNC_W: COP1_D_TRUNC_W(); break; - case R4300i_COP1_FUNCT_CEIL_W: COP1_D_CEIL_W(); break; //added by Witten - case R4300i_COP1_FUNCT_FLOOR_W: COP1_D_FLOOR_W(); break; //added by Witten - case R4300i_COP1_FUNCT_CVT_S: COP1_D_CVT_S(); break; - case R4300i_COP1_FUNCT_CVT_W: COP1_D_CVT_W(); break; - case R4300i_COP1_FUNCT_CVT_L: COP1_D_CVT_L(); break; + case R4300i_COP1_FUNCT_ADD: m_RecompilerOps->COP1_D_ADD(); break; + case R4300i_COP1_FUNCT_SUB: m_RecompilerOps->COP1_D_SUB(); break; + case R4300i_COP1_FUNCT_MUL: m_RecompilerOps->COP1_D_MUL(); break; + case R4300i_COP1_FUNCT_DIV: m_RecompilerOps->COP1_D_DIV(); break; + case R4300i_COP1_FUNCT_ABS: m_RecompilerOps->COP1_D_ABS(); break; + case R4300i_COP1_FUNCT_NEG: m_RecompilerOps->COP1_D_NEG(); break; + case R4300i_COP1_FUNCT_SQRT: m_RecompilerOps->COP1_D_SQRT(); break; + case R4300i_COP1_FUNCT_MOV: m_RecompilerOps->COP1_D_MOV(); break; + case R4300i_COP1_FUNCT_ROUND_L: m_RecompilerOps->COP1_D_ROUND_L(); break; + case R4300i_COP1_FUNCT_TRUNC_L: m_RecompilerOps->COP1_D_TRUNC_L(); break; + case R4300i_COP1_FUNCT_CEIL_L: m_RecompilerOps->COP1_D_CEIL_L(); break; + case R4300i_COP1_FUNCT_FLOOR_L: m_RecompilerOps->COP1_D_FLOOR_L(); break; + case R4300i_COP1_FUNCT_ROUND_W: m_RecompilerOps->COP1_D_ROUND_W(); break; + case R4300i_COP1_FUNCT_TRUNC_W: m_RecompilerOps->COP1_D_TRUNC_W(); break; + case R4300i_COP1_FUNCT_CEIL_W: m_RecompilerOps->COP1_D_CEIL_W(); break; + case R4300i_COP1_FUNCT_FLOOR_W: m_RecompilerOps->COP1_D_FLOOR_W(); break; + case R4300i_COP1_FUNCT_CVT_S: m_RecompilerOps->COP1_D_CVT_S(); break; + case R4300i_COP1_FUNCT_CVT_W: m_RecompilerOps->COP1_D_CVT_W(); break; + case R4300i_COP1_FUNCT_CVT_L: m_RecompilerOps->COP1_D_CVT_L(); break; case R4300i_COP1_FUNCT_C_F: case R4300i_COP1_FUNCT_C_UN: case R4300i_COP1_FUNCT_C_EQ: case R4300i_COP1_FUNCT_C_UEQ: case R4300i_COP1_FUNCT_C_OLT: case R4300i_COP1_FUNCT_C_ULT: @@ -1093,136 +668,135 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) case R4300i_COP1_FUNCT_C_SEQ: case R4300i_COP1_FUNCT_C_NGL: case R4300i_COP1_FUNCT_C_LT: case R4300i_COP1_FUNCT_C_NGE: case R4300i_COP1_FUNCT_C_LE: case R4300i_COP1_FUNCT_C_NGT: - COP1_D_CMP(); break; + m_RecompilerOps->COP1_D_CMP(); break; default: - UnknownOpcode(); break; + m_RecompilerOps->UnknownOpcode(); break; } break; case R4300i_COP1_W: - switch (m_Opcode.funct) + switch (Opcode.funct) { - case R4300i_COP1_FUNCT_CVT_S: COP1_W_CVT_S(); break; - case R4300i_COP1_FUNCT_CVT_D: COP1_W_CVT_D(); break; + case R4300i_COP1_FUNCT_CVT_S: m_RecompilerOps->COP1_W_CVT_S(); break; + case R4300i_COP1_FUNCT_CVT_D: m_RecompilerOps->COP1_W_CVT_D(); break; default: - UnknownOpcode(); break; + m_RecompilerOps->UnknownOpcode(); break; } break; case R4300i_COP1_L: - switch (m_Opcode.funct) + switch (Opcode.funct) { - case R4300i_COP1_FUNCT_CVT_S: COP1_L_CVT_S(); break; - case R4300i_COP1_FUNCT_CVT_D: COP1_L_CVT_D(); break; + case R4300i_COP1_FUNCT_CVT_S: m_RecompilerOps->COP1_L_CVT_S(); break; + case R4300i_COP1_FUNCT_CVT_D: m_RecompilerOps->COP1_L_CVT_D(); break; default: - UnknownOpcode(); break; + m_RecompilerOps->UnknownOpcode(); break; } break; default: - UnknownOpcode(); break; + m_RecompilerOps->UnknownOpcode(); break; } break; - case R4300i_BEQL: Compile_BranchLikely(CRecompilerOps::CompareTypeBEQ, false); break; - case R4300i_BNEL: Compile_BranchLikely(CRecompilerOps::CompareTypeBNE, false); break; - case R4300i_BGTZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBGTZ, false); break; - case R4300i_BLEZL:Compile_BranchLikely(CRecompilerOps::CompareTypeBLEZ, false); break; - case R4300i_DADDIU: DADDIU(); break; - case R4300i_LDL: LDL(); break; - case R4300i_LDR: LDR(); break; - case R4300i_LB: LB(); break; - case R4300i_LH: LH(); break; - case R4300i_LWL: LWL(); break; - case R4300i_LW: LW(); break; - case R4300i_LBU: LBU(); break; - case R4300i_LHU: LHU(); break; - case R4300i_LWR: LWR(); break; - case R4300i_LWU: LWU(); break; //added by Witten - case R4300i_SB: SB(); break; - case R4300i_SH: SH(); break; - case R4300i_SWL: SWL(); break; - case R4300i_SW: SW(); break; - case R4300i_SWR: SWR(); break; - case R4300i_SDL: SDL(); break; - case R4300i_SDR: SDR(); break; - case R4300i_CACHE: CACHE(); break; - case R4300i_LL: LL(); break; - case R4300i_LWC1: LWC1(); break; - case R4300i_LDC1: LDC1(); break; - case R4300i_SC: SC(); break; - case R4300i_LD: LD(); break; - case R4300i_SWC1: SWC1(); break; - case R4300i_SDC1: SDC1(); break; - case R4300i_SD: SD(); break; + case R4300i_BEQL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBEQ, false); break; + case R4300i_BNEL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBNE, false); break; + case R4300i_BGTZL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBGTZ, false); break; + case R4300i_BLEZL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBLEZ, false); break; + case R4300i_DADDIU: m_RecompilerOps->DADDIU(); break; + case R4300i_LDL: m_RecompilerOps->LDL(); break; + case R4300i_LDR: m_RecompilerOps->LDR(); break; + case R4300i_LB: m_RecompilerOps->LB(); break; + case R4300i_LH: m_RecompilerOps->LH(); break; + case R4300i_LWL: m_RecompilerOps->LWL(); break; + case R4300i_LW: m_RecompilerOps->LW(); break; + case R4300i_LBU: m_RecompilerOps->LBU(); break; + case R4300i_LHU: m_RecompilerOps->LHU(); break; + case R4300i_LWR: m_RecompilerOps->LWR(); break; + case R4300i_LWU: m_RecompilerOps->LWU(); break; + case R4300i_SB: m_RecompilerOps->SB(); break; + case R4300i_SH: m_RecompilerOps->SH(); break; + case R4300i_SWL: m_RecompilerOps->SWL(); break; + case R4300i_SW: m_RecompilerOps->SW(); break; + case R4300i_SWR: m_RecompilerOps->SWR(); break; + case R4300i_SDL: m_RecompilerOps->SDL(); break; + case R4300i_SDR: m_RecompilerOps->SDR(); break; + case R4300i_CACHE: m_RecompilerOps->CACHE(); break; + case R4300i_LL: m_RecompilerOps->LL(); break; + case R4300i_LWC1: m_RecompilerOps->LWC1(); break; + case R4300i_LDC1: m_RecompilerOps->LDC1(); break; + case R4300i_SC: m_RecompilerOps->SC(); break; + case R4300i_LD: m_RecompilerOps->LD(); break; + case R4300i_SWC1: m_RecompilerOps->SWC1(); break; + case R4300i_SDC1: m_RecompilerOps->SDC1(); break; + case R4300i_SD: m_RecompilerOps->SD(); break; default: - UnknownOpcode(); break; + m_RecompilerOps->UnknownOpcode(); break; } - if (!g_System->bRegCaching()) { m_RegWorkingSet.WriteBackRegisters(); } - m_RegWorkingSet.UnMap_AllFPRs(); + m_RecompilerOps->PostCompileOpcode(); - if ((m_CompilePC & 0xFFC) == 0xFFC) + if ((m_RecompilerOps->GetCurrentPC() & 0xFFC) == 0xFFC) { - if (m_NextInstruction == DO_DELAY_SLOT) + if (m_RecompilerOps->GetNextStepType() == DO_DELAY_SLOT) { g_Notify->BreakPoint(__FILE__, __LINE__); } - if (m_NextInstruction == NORMAL) + if (m_RecompilerOps->GetNextStepType() == NORMAL) { if (m_DelaySlot) { - CompileExit(m_CompilePC, m_Jump.TargetPC, m_RegWorkingSet, CExitInfo::Normal, true, NULL); + m_RecompilerOps->CompileExit(m_RecompilerOps->GetCurrentPC(), m_Jump.TargetPC, m_RecompilerOps->GetRegWorkingSet(), CExitInfo::Normal, true); } else { - CompileExit(m_CompilePC, m_CompilePC + 4, m_RegWorkingSet, CExitInfo::Normal, true, NULL); + m_RecompilerOps->CompileExit(m_RecompilerOps->GetCurrentPC(), m_RecompilerOps->GetCurrentPC() + 4, m_RecompilerOps->GetRegWorkingSet(), CExitInfo::Normal, true); } - m_NextInstruction = END_BLOCK; + m_RecompilerOps->SetNextStepType(END_BLOCK); } } - switch (m_NextInstruction) + switch (m_RecompilerOps->GetNextStepType()) { case NORMAL: - m_CompilePC += 4; + m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() + 4); break; case DO_DELAY_SLOT: - m_NextInstruction = DELAY_SLOT; - m_CompilePC += 4; + m_RecompilerOps->SetNextStepType(DELAY_SLOT); + m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() + 4); break; case DELAY_SLOT: - m_NextInstruction = DELAY_SLOT_DONE; - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); - m_CompilePC -= 4; + m_RecompilerOps->SetNextStepType(DELAY_SLOT_DONE); + m_RecompilerOps->GetRegWorkingSet().SetBlockCycleCount(m_RecompilerOps->GetRegWorkingSet().GetBlockCycleCount() - g_System->CountPerOp()); + m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() - 4); break; } if (m_DelaySlot) { - if ((CompilePC() & 0xFFC) != 0xFFC && m_Jump.JumpPC != (uint32_t)-1) + if ((m_RecompilerOps->GetCurrentPC() & 0xFFC) != 0xFFC && m_Jump.JumpPC != (uint32_t)-1) { - m_CompilePC = m_Jump.JumpPC; - m_Jump.RegSet = m_RegWorkingSet; + m_RecompilerOps->SetCurrentPC(m_Jump.JumpPC); + m_Jump.RegSet = m_RecompilerOps->GetRegWorkingSet(); m_Jump.FallThrough = true; GenerateSectionLinkage(); } else { - CompileExit(m_Jump.JumpPC, m_Jump.TargetPC, m_RegWorkingSet, CExitInfo::Normal, true, NULL); + m_RecompilerOps->CompileExit(m_Jump.JumpPC, m_Jump.TargetPC, m_RecompilerOps->GetRegWorkingSet(), CExitInfo::Normal, true); } - m_NextInstruction = END_BLOCK; + m_RecompilerOps->SetNextStepType(END_BLOCK); } - else if (m_NextInstruction != END_BLOCK && m_CompilePC == ContinueSectionPC) + else if (m_RecompilerOps->GetNextStepType() != END_BLOCK && m_RecompilerOps->GetCurrentPC() == ContinueSectionPC) { - if (m_NextInstruction != NORMAL) + if (m_RecompilerOps->GetNextStepType() != NORMAL) { g_Notify->BreakPoint(__FILE__, __LINE__); } - m_CompilePC -= 4; - m_Cont.RegSet = m_RegWorkingSet; + m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() - 4); + m_Cont.RegSet = m_RecompilerOps->GetRegWorkingSet(); m_Cont.FallThrough = true; - m_Cont.JumpPC = m_CompilePC; + m_Cont.JumpPC = m_RecompilerOps->GetCurrentPC(); GenerateSectionLinkage(); - m_NextInstruction = END_BLOCK; + m_RecompilerOps->SetNextStepType(END_BLOCK); } - } while (m_NextInstruction != END_BLOCK); + } while (m_RecompilerOps->GetNextStepType() != END_BLOCK); return true; } @@ -1231,7 +805,7 @@ void CCodeSection::AddParent(CCodeSection * Parent) if (this == NULL) { return; } if (Parent == NULL) { - m_RegWorkingSet = m_RegEnter; + m_RecompilerOps->SetRegWorkingSet(m_RegEnter); return; } @@ -1259,9 +833,9 @@ void CCodeSection::AddParent(CCodeSection * Parent) { g_Notify->DisplayError("How are these sections joined?????"); } - m_RegWorkingSet = m_RegEnter; } - else { + else + { if (Parent->m_ContinueSection == this) { TestRegConstantStates(Parent->m_Cont.RegSet, m_RegEnter); @@ -1270,8 +844,8 @@ void CCodeSection::AddParent(CCodeSection * Parent) { TestRegConstantStates(Parent->m_Jump.RegSet, m_RegEnter); } - m_RegWorkingSet = m_RegEnter; } + m_RecompilerOps->SetRegWorkingSet(m_RegEnter); } void CCodeSection::SwitchParent(CCodeSection * OldParent, CCodeSection * NewParent) @@ -1504,464 +1078,6 @@ bool CCodeSection::IsAllParentLoops(CCodeSection * Parent, bool IgnoreIfCompiled return true; } -bool CCodeSection::SetupRegisterForLoop() -{ - CRegInfo OriginalReg = m_RegWorkingSet; - if (!LoopAnalysis(m_BlockInfo, this).SetupRegisterForLoop()) - { - return false; - } - for (int i = 1; i < 32; i++) - { - if (OriginalReg.GetMipsRegState(i) != m_RegEnter.GetMipsRegState(i)) - { - UnMap_GPR(i, true); - } - } - return true; -} - -bool CCodeSection::InheritParentInfo() -{ - if (m_CompiledLocation == NULL) - { - m_CompiledLocation = *g_RecompPos; - DisplaySectionInformation(); - m_CompiledLocation = NULL; - } - else - { - DisplaySectionInformation(); - } - - if (m_ParentSection.empty()) - { - m_RegWorkingSet = m_RegEnter; - return true; - } - - if (m_ParentSection.size() == 1) - { - CCodeSection * Parent = *(m_ParentSection.begin()); - if (Parent->m_CompiledLocation == NULL) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - CJumpInfo * JumpInfo = this == Parent->m_ContinueSection ? &Parent->m_Cont : &Parent->m_Jump; - - m_RegEnter = JumpInfo->RegSet; - if (JumpInfo->LinkLocation != NULL) - { - CPU_Message(" Section_%d:", m_SectionID); - SetJump32(JumpInfo->LinkLocation, (uint32_t *)*g_RecompPos); - if (JumpInfo->LinkLocation2 != NULL) - { - SetJump32(JumpInfo->LinkLocation2, (uint32_t *)*g_RecompPos); - } - } - m_RegWorkingSet = m_RegEnter; - return true; - } - - //Multiple Parents - BLOCK_PARENT_LIST ParentList; - SECTION_LIST::iterator iter; - for (iter = m_ParentSection.begin(); iter != m_ParentSection.end(); iter++) - { - CCodeSection * Parent = *iter; - BLOCK_PARENT BlockParent; - - if (Parent->m_CompiledLocation == NULL) { continue; } - if (Parent->m_JumpSection != Parent->m_ContinueSection) - { - BlockParent.Parent = Parent; - BlockParent.JumpInfo = this == Parent->m_ContinueSection ? &Parent->m_Cont : &Parent->m_Jump; - ParentList.push_back(BlockParent); - } - else - { - BlockParent.Parent = Parent; - BlockParent.JumpInfo = &Parent->m_Cont; - ParentList.push_back(BlockParent); - BlockParent.Parent = Parent; - BlockParent.JumpInfo = &Parent->m_Jump; - ParentList.push_back(BlockParent); - } - } - size_t NoOfCompiledParents = ParentList.size(); - if (NoOfCompiledParents == 0) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - return false; - } - - // Add all the uncompiled blocks to the end of the list - for (iter = m_ParentSection.begin(); iter != m_ParentSection.end(); iter++) - { - CCodeSection * Parent = *iter; - BLOCK_PARENT BlockParent; - - if (Parent->m_CompiledLocation != NULL) { continue; } - if (Parent->m_JumpSection != Parent->m_ContinueSection) - { - BlockParent.Parent = Parent; - BlockParent.JumpInfo = this == Parent->m_ContinueSection ? &Parent->m_Cont : &Parent->m_Jump; - ParentList.push_back(BlockParent); - } - else - { - BlockParent.Parent = Parent; - BlockParent.JumpInfo = &Parent->m_Cont; - ParentList.push_back(BlockParent); - BlockParent.Parent = Parent; - BlockParent.JumpInfo = &Parent->m_Jump; - ParentList.push_back(BlockParent); - } - } - int FirstParent = -1; - for (size_t i = 0; i < NoOfCompiledParents; i++) - { - if (!ParentList[i].JumpInfo->FallThrough) - { - continue; - } - if (FirstParent != -1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - FirstParent = i; - } - if (FirstParent == -1) - { - FirstParent = 0; - } - - //Link First Parent to start - CCodeSection * Parent = ParentList[FirstParent].Parent; - CJumpInfo * JumpInfo = ParentList[FirstParent].JumpInfo; - - m_RegWorkingSet = JumpInfo->RegSet; - m_RegWorkingSet.ResetX86Protection(); - - if (JumpInfo->LinkLocation != NULL) - { - CPU_Message(" Section_%d (from %d):", m_SectionID, Parent->m_SectionID); - SetJump32(JumpInfo->LinkLocation, (uint32_t *)*g_RecompPos); - JumpInfo->LinkLocation = NULL; - if (JumpInfo->LinkLocation2 != NULL) - { - SetJump32(JumpInfo->LinkLocation2, (uint32_t *)*g_RecompPos); - JumpInfo->LinkLocation2 = NULL; - } - } - - if (JumpInfo->ExitReason == CExitInfo::Normal_NoSysCheck) - { - if (JumpInfo->RegSet.GetBlockCycleCount() != 0) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (JumpInfo->JumpPC != (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - else - { - UpdateCounters(m_RegWorkingSet, m_EnterPC < JumpInfo->JumpPC, true); - if (JumpInfo->JumpPC == (uint32_t)-1) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (m_EnterPC <= JumpInfo->JumpPC) - { - CPU_Message("CompileSystemCheck 10"); - CompileSystemCheck(m_EnterPC, m_RegWorkingSet); - } - } - JumpInfo->FallThrough = false; - - //Fix up initial state - UnMap_AllFPRs(); - - //determine loop reg usage - if (m_InLoop && ParentList.size() > 1) - { - if (!SetupRegisterForLoop()) { return false; } - m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); - } - - for (size_t i = 0; i < ParentList.size(); i++) - { - x86Reg MemoryStackPos; - int i2; - - if (i == (size_t)FirstParent) { continue; } - Parent = ParentList[i].Parent; - if (Parent->m_CompiledLocation == NULL) - { - continue; - } - CRegInfo * RegSet = &ParentList[i].JumpInfo->RegSet; - - if (m_RegWorkingSet.GetRoundingModel() != RegSet->GetRoundingModel()) { m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); } - - //Find Parent MapRegState - MemoryStackPos = x86_Unknown; - for (i2 = 0; i2 < sizeof(x86_Registers) / sizeof(x86_Registers[0]); i2++) - { - if (RegSet->GetX86Mapped(x86_Registers[i2]) == CRegInfo::Stack_Mapped) - { - MemoryStackPos = x86_Registers[i2]; - break; - } - } - if (MemoryStackPos == x86_Unknown) - { - // if the memory stack position is not mapped then unmap it - x86Reg MemStackReg = Get_MemoryStack(); - if (MemStackReg != x86_Unknown) - { - UnMap_X86reg(MemStackReg); - } - } - - for (i2 = 1; i2 < 32; i2++) - { - if (Is32BitMapped(i2)) - { - switch (RegSet->GetMipsRegState(i2)) - { - case CRegInfo::STATE_MAPPED_64: Map_GPR_64bit(i2, i2); break; - case CRegInfo::STATE_MAPPED_32_ZERO: break; - case CRegInfo::STATE_MAPPED_32_SIGN: - if (IsUnsigned(i2)) - { - m_RegWorkingSet.SetMipsRegState(i2, CRegInfo::STATE_MAPPED_32_SIGN); - } - break; - case CRegInfo::STATE_CONST_64: Map_GPR_64bit(i2, i2); break; - case CRegInfo::STATE_CONST_32_SIGN: - if ((RegSet->GetMipsRegLo_S(i2) < 0) && IsUnsigned(i2)) - { - m_RegWorkingSet.SetMipsRegState(i2, CRegInfo::STATE_MAPPED_32_SIGN); - } - break; - case CRegInfo::STATE_UNKNOWN: - if (g_System->b32BitCore()) - { - Map_GPR_32bit(i2, true, i2); - } - else - { - //Map_GPR_32bit(i2,true,i2); - Map_GPR_64bit(i2, i2); //?? - //UnMap_GPR(Section,i2,true); ?? - } - break; - default: - CPU_Message("Unknown CPU State(%d) in InheritParentInfo", GetMipsRegState(i2)); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - if (IsConst(i2)) { - if (GetMipsRegState(i2) != RegSet->GetMipsRegState(i2)) - { - switch (RegSet->GetMipsRegState(i2)) - { - case CRegInfo::STATE_MAPPED_64: - Map_GPR_64bit(i2, i2); - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - if (Is32Bit(i2)) - { - Map_GPR_32bit(i2, (GetMipsRegLo(i2) & 0x80000000) != 0, i2); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - break; - case CRegInfo::STATE_MAPPED_32_SIGN: - if (Is32Bit(i2)) - { - Map_GPR_32bit(i2, true, i2); - } - else - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - break; - case CRegInfo::STATE_UNKNOWN: - if (g_System->b32BitCore()) - { - Map_GPR_32bit(i2, true, i2); - } - else - { - Map_GPR_64bit(i2, i2); - } - break; - default: - CPU_Message("Unknown CPU State(%d) in InheritParentInfo", RegSet->GetMipsRegState(i2)); - g_Notify->BreakPoint(__FILE__, __LINE__); - break; - } - } - else if (Is32Bit(i2) && GetMipsRegLo(i2) != RegSet->GetMipsRegLo(i2)) - { - Map_GPR_32bit(i2, true, i2); - } - else if (Is64Bit(i2) && GetMipsReg(i2) != RegSet->GetMipsReg(i2)) - { - Map_GPR_32bit(i2, true, i2); - } - } - ResetX86Protection(); - } - - if (MemoryStackPos > 0) - { - Map_MemoryStack(MemoryStackPos, true); - } - } - m_RegEnter = m_RegWorkingSet; - - //Sync registers for different blocks - stdstr_f Label("Section_%d", m_SectionID); - int CurrentParent = FirstParent; - bool NeedSync = false; - for (size_t i = 0; i < NoOfCompiledParents; i++) - { - CRegInfo * RegSet; - int i2; - - if (i == (size_t)FirstParent) { continue; } - Parent = ParentList[i].Parent; - JumpInfo = ParentList[i].JumpInfo; - RegSet = &ParentList[i].JumpInfo->RegSet; - - if (JumpInfo->RegSet.GetBlockCycleCount() != 0) { NeedSync = true; } - - for (i2 = 0; !NeedSync && i2 < 8; i2++) - { - if (m_RegWorkingSet.FpuMappedTo(i2) == (uint32_t)-1) - { - NeedSync = true; - } - } - - for (i2 = 0; !NeedSync && i2 < sizeof(x86_Registers) / sizeof(x86_Registers[0]); i2++) - { - if (m_RegWorkingSet.GetX86Mapped(x86_Registers[i2]) == CRegInfo::Stack_Mapped) - { - if (m_RegWorkingSet.GetX86Mapped(x86_Registers[i2]) != RegSet->GetX86Mapped(x86_Registers[i2])) - { - NeedSync = true; - } - break; - } - } - for (i2 = 0; !NeedSync && i2 < 32; i2++) - { - if (NeedSync == true) { break; } - if (m_RegWorkingSet.GetMipsRegState(i2) != RegSet->GetMipsRegState(i2)) - { - NeedSync = true; - continue; - } - switch (m_RegWorkingSet.GetMipsRegState(i2)) - { - case CRegInfo::STATE_UNKNOWN: break; - case CRegInfo::STATE_MAPPED_64: - if (GetMipsRegMapHi(i2) != RegSet->GetMipsRegMapHi(i2) || - GetMipsRegMapLo(i2) != RegSet->GetMipsRegMapLo(i2)) - { - NeedSync = true; - } - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - case CRegInfo::STATE_MAPPED_32_SIGN: - if (GetMipsRegMapLo(i2) != RegSet->GetMipsRegMapLo(i2)) - { - //DisplayError(L"Parent: %d",Parent->SectionID); - NeedSync = true; - } - break; - case CRegInfo::STATE_CONST_32_SIGN: - if (GetMipsRegLo(i2) != RegSet->GetMipsRegLo(i2)) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - NeedSync = true; - } - break; - default: - WriteTrace(TraceRecompiler, TraceError, "Unhandled Reg state %d\nin InheritParentInfo", GetMipsRegState(i2)); - g_Notify->BreakPoint(__FILE__, __LINE__); - } - } - if (NeedSync == false) { continue; } - Parent = ParentList[CurrentParent].Parent; - JumpInfo = ParentList[CurrentParent].JumpInfo; - JmpLabel32(Label.c_str(), 0); - JumpInfo->LinkLocation = (uint32_t *)(*g_RecompPos - 4); - JumpInfo->LinkLocation2 = NULL; - - CurrentParent = i; - Parent = ParentList[CurrentParent].Parent; - JumpInfo = ParentList[CurrentParent].JumpInfo; - CPU_Message(" Section_%d (from %d):", m_SectionID, Parent->m_SectionID); - if (JumpInfo->LinkLocation != NULL) - { - SetJump32(JumpInfo->LinkLocation, (uint32_t *)*g_RecompPos); - JumpInfo->LinkLocation = NULL; - if (JumpInfo->LinkLocation2 != NULL) - { - SetJump32(JumpInfo->LinkLocation2, (uint32_t *)*g_RecompPos); - JumpInfo->LinkLocation2 = NULL; - } - } - //if (m_EnterPC == 0x8031CE44 && m_SectionID == 6) - //{ - // g_Notify->BreakPoint(__FILE__, __LINE__); - //} - m_RegWorkingSet = JumpInfo->RegSet; - if (m_EnterPC < JumpInfo->JumpPC) - { - UpdateCounters(m_RegWorkingSet, true, true); - CPU_Message("CompileSystemCheck 11"); - CompileSystemCheck(m_EnterPC, m_RegWorkingSet); - } - else - { - UpdateCounters(m_RegWorkingSet, false, true); - } - SyncRegState(m_RegEnter); //Sync - m_RegEnter = m_RegWorkingSet; - } - - for (size_t i = 0; i < NoOfCompiledParents; i++) - { - Parent = ParentList[i].Parent; - JumpInfo = ParentList[i].JumpInfo; - - if (JumpInfo->LinkLocation != NULL) - { - SetJump32(JumpInfo->LinkLocation, (uint32_t *)*g_RecompPos); - JumpInfo->LinkLocation = NULL; - if (JumpInfo->LinkLocation2 != NULL) - { - SetJump32(JumpInfo->LinkLocation2, (uint32_t *)*g_RecompPos); - JumpInfo->LinkLocation2 = NULL; - } - } - } - - CPU_Message(" Section_%d:", m_SectionID); - m_RegWorkingSet.SetBlockCycleCount(0); - return true; -} - bool CCodeSection::DisplaySectionInformation(uint32_t ID, uint32_t Test) { if (!g_bRecompilerLogging) diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.h b/Source/Project64-core/N64System/Recompiler/CodeSection.h index 07a92d831..6503b6488 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.h +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.h @@ -14,8 +14,7 @@ class CCodeBlock; -class CCodeSection : - public CRecompilerOps +class CCodeSection { public: typedef std::list SECTION_LIST; @@ -26,7 +25,6 @@ public: void SetDelaySlot(); void SetJumpAddress(uint32_t JumpPC, uint32_t TargetPC, bool PermLoop); void SetContinueAddress(uint32_t JumpPC, uint32_t TargetPC); - void CompileCop1Test(); bool GenerateNativeCode(uint32_t Test); void GenerateSectionLinkage(); void DetermineLoop(uint32_t Test, uint32_t Test2, uint32_t TestID); @@ -53,6 +51,7 @@ public: uint8_t * m_CompiledLocation; bool m_InLoop; bool m_DelaySlot; + CRecompilerOps * & m_RecompilerOps; /* Register Info */ CRegInfo m_RegEnter; @@ -69,9 +68,7 @@ private: void UnlinkParent(CCodeSection * Parent, bool ContinueSection); void InheritConstants(); void TestRegConstantStates(CRegInfo & Base, CRegInfo & Reg); - void SyncRegState(const CRegInfo & SyncTo); bool IsAllParentLoops(CCodeSection * Parent, bool IgnoreIfCompiled, uint32_t Test); bool ParentContinue(); - bool InheritParentInfo(); bool SetupRegisterForLoop(); }; diff --git a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp index 27088caa9..f32c48a6f 100644 --- a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp +++ b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp @@ -26,11 +26,11 @@ bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); LoopAnalysis::LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section) : -m_EnterSection(Section), -m_BlockInfo(CodeBlock), -m_PC((uint32_t)-1), -m_NextInstruction(NORMAL), -m_Test(m_BlockInfo->NextTest()) + m_EnterSection(Section), + m_BlockInfo(CodeBlock), + m_PC((uint32_t)-1), + m_NextInstruction(NORMAL), + m_Test(m_BlockInfo->NextTest()) { memset(&m_Command, 0, sizeof(m_Command)); } diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 7eb878ea0..25c6449c7 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -18,8 +18,11 @@ #include #include #include +#include +#include #include #include +#include #include CCodeSection * CRecompilerOps::m_Section = NULL; @@ -30,56 +33,127 @@ OPCODE CRecompilerOps::m_Opcode; uint32_t CRecompilerOps::m_BranchCompare = 0; uint32_t CRecompilerOps::m_TempValue = 0; -void CRecompilerOps::Compile_StoreInstructClean(x86Reg AddressReg, int32_t Length) +/*int TestValue = 0; +void TestFunc() { - if (!g_System->bSMM_StoreInstruc()) +TestValue += 1; +if (TestValue >= 4) +{ +g_Notify->BreakPoint(__FILE__, __LINE__); +} +}*/ + +void CRecompilerOps::PreCompileOpcode(void) +{ + /*if (m_CompilePC == 0x803245C4 && m_NextInstruction == NORMAL) { - return; + X86BreakPoint(__FILE__, __LINE__); + }*/ + + /*if (m_CompilePC >= 0x80000000 && m_CompilePC <= 0x80400000 && m_NextInstruction == NORMAL) + { + m_RegWorkingSet.WriteBackRegisters(); + UpdateCounters(m_RegWorkingSet, false, true); + MoveConstToVariable(m_CompilePC, &g_Reg->m_PROGRAM_COUNTER, "PROGRAM_COUNTER"); + if (g_SyncSystem) { + MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); } + }*/ + + /*if ((m_CompilePC == 0x8031C0E4 || m_CompilePC == 0x8031C118 || + m_CompilePC == 0x8031CD88 || m_CompilePC == 0x8031CE24 || + m_CompilePC == 0x8031CE30 || m_CompilePC == 0x8031CE40) && m_NextInstruction == NORMAL) + { + m_RegWorkingSet.WriteBackRegisters(); + UpdateCounters(m_RegWorkingSet,false,true); + MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); + if (g_SyncSystem) { + MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); + } + }*/ + + /*if (m_CompilePC == 0x801C1B88) + { + BeforeCallDirect(m_RegWorkingSet); + Call_Direct(AddressOf(TestFunc), "TestFunc"); + AfterCallDirect(m_RegWorkingSet); + }*/ + + /*if (m_CompilePC >= 0x801C1AF8 && m_CompilePC <= 0x801C1C00 && m_NextInstruction == NORMAL) + { + UpdateCounters(m_RegWorkingSet,false,true); + MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); + if (g_SyncSystem) { + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystemPC), "CN64System::SyncSystemPC"); + AfterCallDirect(m_RegWorkingSet); + } + }*/ + + /*if ((m_CompilePC == 0x80263900) && m_NextInstruction == NORMAL) + { + X86BreakPoint(__FILEW__,__LINE__); + }*/ + + /*if ((m_CompilePC >= 0x80325D80 && m_CompilePC <= 0x80325DF0) && m_NextInstruction == NORMAL) + { + m_RegWorkingSet.WriteBackRegisters(); + UpdateCounters(m_RegWorkingSet,false,true); + MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); + if (g_SyncSystem) { + MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); + } + }*/ + /*if ((m_CompilePC == 0x80324E14) && m_NextInstruction == NORMAL) + { + X86BreakPoint(__FILEW__,__LINE__); + }*/ + + /*if (m_CompilePC == 0x80324E18 && m_NextInstruction == NORMAL) + { + m_RegWorkingSet.WriteBackRegisters(); + UpdateCounters(m_RegWorkingSet,false,true); + MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); + if (g_SyncSystem) { + MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); + } + }*/ + /*if (m_CompilePC >= 0x80324E00 && m_CompilePC <= 0x80324E18 && m_NextInstruction == NORMAL) + { + m_RegWorkingSet.WriteBackRegisters(); + UpdateCounters(m_RegWorkingSet,false,true); + MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); + if (g_SyncSystem) { + MoveConstToX86reg((uint32_t)g_BaseSystem,x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); + } + }*/ + /* if (m_CompilePC == 0x803245CC && m_NextInstruction == NORMAL) + { + //m_RegWorkingSet.UnMap_AllFPRs(); g_Notify->BreakPoint(__FILE__, __LINE__); + //X86HardBreakPoint(); + //X86BreakPoint(__FILEW__,__LINE__); + //m_RegWorkingSet.UnMap_AllFPRs(); + }*/ + /*if (m_CompilePC >= 0x80179DC4 && m_CompilePC <= 0x80179DF0 && m_NextInstruction == NORMAL) + { + m_RegWorkingSet.UnMap_AllFPRs(); + }*/ - /* - stdstr_f strLen("%d",Length); - UnMap_AllFPRs(); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + m_RegWorkingSet.ResetX86Protection(); +} - /*x86Reg StoreTemp1 = Map_TempReg(x86_Any,-1,false); - MoveX86RegToX86Reg(AddressReg, StoreTemp1); - AndConstToX86Reg(StoreTemp1,0xFFC);*/ - BeforeCallDirect(m_RegWorkingSet); - PushImm32("CRecompiler::Remove_StoreInstruc", CRecompiler::Remove_StoreInstruc); - PushImm32(Length); - Push(AddressReg); - MoveConstToX86reg((uint32_t)g_Recompiler, x86_ECX); - Call_Direct(AddressOf(&CRecompiler::ClearRecompCode_Virt), "CRecompiler::ClearRecompCode_Virt"); - AfterCallDirect(m_RegWorkingSet); - /*JmpLabel8("MemCheckDone",0); - uint8_t * MemCheckDone = *g_RecompPos - 1; - - CPU_Message(" "); - CPU_Message(" NotDelaySlot:"); - SetJump8(NotDelaySlotJump,*g_RecompPos); - - MoveX86RegToX86Reg(AddressReg, StoreTemp1); - ShiftRightUnsignImmed(StoreTemp1,12); - LeaRegReg(StoreTemp1,StoreTemp1,(uint32_t)&(g_Recompiler->FunctionTable()[0]),Multip_x4); - CompConstToX86regPointer(StoreTemp1,0); - JeLabel8("MemCheckDone",0); - uint8_t * MemCheckDone2 = *g_RecompPos - 1; - - BeforeCallDirect(m_RegWorkingSet); - PushImm32("CRecompiler::Remove_StoreInstruc",CRecompiler::Remove_StoreInstruc); - PushImm32(strLen.c_str(),Length); - Push(AddressReg); - MoveConstToX86reg((uint32_t)g_Recompiler,x86_ECX); - Call_Direct(AddressOf(&CRecompiler::ClearRecompCode_Virt), "CRecompiler::ClearRecompCode_Virt"); - AfterCallDirect(m_RegWorkingSet); - - CPU_Message(" "); - CPU_Message(" MemCheckDone:"); - SetJump8(MemCheckDone,*g_RecompPos); - SetJump8(MemCheckDone2,*g_RecompPos); - - X86Protected(StoreTemp1) = false;*/ +void CRecompilerOps::PostCompileOpcode(void) +{ + if (!g_System->bRegCaching()) { m_RegWorkingSet.WriteBackRegisters(); } + m_RegWorkingSet.UnMap_AllFPRs(); } void CRecompilerOps::CompileReadTLBMiss(uint32_t VirtualAddress, x86Reg LookUpReg) @@ -133,7 +207,7 @@ void CRecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE Bran CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT) { - m_Section->CompileCop1Test(); + CompileCop1Test(); } if (m_CompilePC + ((int16_t)m_Opcode.offset << 2) + 4 == m_CompilePC + 8) { @@ -446,7 +520,7 @@ void CRecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link) if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT) { - m_Section->CompileCop1Test();; + CompileCop1Test(); } if (!g_System->bLinkBlocks() || (m_CompilePC & 0xFFC) == 0xFFC) { @@ -3001,16 +3075,16 @@ void CRecompilerOps::LW_KnownAddress(x86Reg Reg, uint32_t VAddr) } break; case 0x04100000: - { - static uint32_t TempValue = 0; - BeforeCallDirect(m_RegWorkingSet); - PushImm32("TempValue", (uint32_t)&TempValue); - PushImm32(PAddr); - MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); - Call_Direct(AddressOf(&CMipsMemoryVM::LW_NonMemory), "CMipsMemoryVM::LW_NonMemory"); - AfterCallDirect(m_RegWorkingSet); - MoveVariableToX86reg(&TempValue, "TempValue", Reg); - } + { + static uint32_t TempValue = 0; + BeforeCallDirect(m_RegWorkingSet); + PushImm32("TempValue", (uint32_t)&TempValue); + PushImm32(PAddr); + MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); + Call_Direct(AddressOf(&CMipsMemoryVM::LW_NonMemory), "CMipsMemoryVM::LW_NonMemory"); + AfterCallDirect(m_RegWorkingSet); + MoveVariableToX86reg(&TempValue, "TempValue", Reg); + } break; case 0x04300000: switch (PAddr) @@ -3857,7 +3931,6 @@ void CRecompilerOps::SW(bool bCheckLLbit) } } - void CRecompilerOps::SWR() { x86Reg TempReg1 = x86_Unknown, TempReg2 = x86_Unknown, Value = x86_Unknown, @@ -4011,7 +4084,7 @@ void CRecompilerOps::LWC1() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if ((m_Opcode.ft & 1) != 0) { if (RegInStack(m_Opcode.ft - 1, CRegInfo::FPU_Double) || RegInStack(m_Opcode.ft - 1, CRegInfo::FPU_Qword)) @@ -4117,7 +4190,7 @@ void CRecompilerOps::LDC1() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); UnMap_FPR(m_Opcode.ft, false); if (IsConst(m_Opcode.base)) @@ -4322,7 +4395,7 @@ void CRecompilerOps::SWC1() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (IsConst(m_Opcode.base)) { @@ -4403,7 +4476,7 @@ void CRecompilerOps::SDC1() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (IsConst(m_Opcode.base)) { @@ -4491,7 +4564,6 @@ void CRecompilerOps::SDC1() } } - void CRecompilerOps::SD() { x86Reg TempReg1, TempReg2; @@ -7695,38 +7767,38 @@ void CRecompilerOps::COP0_MT() break; case 12: //Status { - x86Reg OldStatusReg = Map_TempReg(x86_Any, -1, false); - MoveVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); - if (IsConst(m_Opcode.rt)) - { - MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else if (IsMapped(m_Opcode.rt)) - { - MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - else { - MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); - } - XorVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); - TestConstToX86Reg(STATUS_FR, OldStatusReg); - JeLabel8("FpuFlagFine", 0); - Jump = *g_RecompPos - 1; - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); - Call_Direct(AddressOf(&CRegisters::FixFpuLocations), "CRegisters::FixFpuLocations"); + x86Reg OldStatusReg = Map_TempReg(x86_Any, -1, false); + MoveVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); + if (IsConst(m_Opcode.rt)) + { + MoveConstToVariable(GetMipsRegLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else if (IsMapped(m_Opcode.rt)) + { + MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rt), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + else { + MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rt, false), &_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd]); + } + XorVariableToX86reg(&_CP0[m_Opcode.rd], CRegName::Cop0[m_Opcode.rd], OldStatusReg); + TestConstToX86Reg(STATUS_FR, OldStatusReg); + JeLabel8("FpuFlagFine", 0); + Jump = *g_RecompPos - 1; + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); + Call_Direct(AddressOf(&CRegisters::FixFpuLocations), "CRegisters::FixFpuLocations"); - AfterCallDirect(m_RegWorkingSet); - SetJump8(Jump, *g_RecompPos); + AfterCallDirect(m_RegWorkingSet); + SetJump8(Jump, *g_RecompPos); - //TestConstToX86Reg(STATUS_FR,OldStatusReg); - //BreakPoint(__FILEW__,__LINE__); //CompileExit(m_CompilePC+4,m_RegWorkingSet,ExitResetRecompCode,false,JneLabel32); - BeforeCallDirect(m_RegWorkingSet); - MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); - Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); - AfterCallDirect(m_RegWorkingSet); + //TestConstToX86Reg(STATUS_FR,OldStatusReg); + //BreakPoint(__FILEW__,__LINE__); //CompileExit(m_CompilePC+4,m_RegWorkingSet,ExitResetRecompCode,false,JneLabel32); + BeforeCallDirect(m_RegWorkingSet); + MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); + Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); + AfterCallDirect(m_RegWorkingSet); } - break; + break; case 6: //Wired m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); @@ -7872,7 +7944,7 @@ void CRecompilerOps::COP1_MF() x86Reg TempReg; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); UnMap_FPR(m_Opcode.fs, true); Map_GPR_32bit(m_Opcode.rt, true, -1); @@ -7889,7 +7961,7 @@ void CRecompilerOps::COP1_DMF() char Name[50]; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); UnMap_FPR(m_Opcode.fs, true); Map_GPR_64bit(m_Opcode.rt, -1); @@ -7907,7 +7979,7 @@ void CRecompilerOps::COP1_CF() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fs != 31 && m_Opcode.fs != 0) { @@ -7924,7 +7996,7 @@ void CRecompilerOps::COP1_MT() x86Reg TempReg; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if ((m_Opcode.fs & 1) != 0) { @@ -7958,7 +8030,7 @@ void CRecompilerOps::COP1_DMT() x86Reg TempReg; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if ((m_Opcode.fs & 1) == 0) { @@ -8010,7 +8082,7 @@ void CRecompilerOps::COP1_DMT() void CRecompilerOps::COP1_CT() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fs != 31) { @@ -8044,7 +8116,7 @@ void CRecompilerOps::COP1_S_ADD() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); FixRoundModel(CRegInfo::RoundDefault); Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); @@ -8076,7 +8148,7 @@ void CRecompilerOps::COP1_S_SUB() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); FixRoundModel(CRegInfo::RoundDefault); if (m_Opcode.fd == m_Opcode.ft) @@ -8118,7 +8190,7 @@ void CRecompilerOps::COP1_S_MUL() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); FixRoundModel(CRegInfo::RoundDefault); Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); @@ -8149,7 +8221,7 @@ void CRecompilerOps::COP1_S_DIV() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); FixRoundModel(CRegInfo::RoundDefault); if (m_Opcode.fd == m_Opcode.ft) @@ -8187,7 +8259,7 @@ void CRecompilerOps::COP1_S_DIV() void CRecompilerOps::COP1_S_ABS() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); FixRoundModel(CRegInfo::RoundDefault); Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); fpuAbs(); @@ -8197,7 +8269,7 @@ void CRecompilerOps::COP1_S_ABS() void CRecompilerOps::COP1_S_NEG() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); FixRoundModel(CRegInfo::RoundDefault); Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); fpuNeg(); @@ -8207,7 +8279,7 @@ void CRecompilerOps::COP1_S_NEG() void CRecompilerOps::COP1_S_SQRT() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); FixRoundModel(CRegInfo::RoundDefault); Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); fpuSqrt(); @@ -8217,7 +8289,7 @@ void CRecompilerOps::COP1_S_SQRT() void CRecompilerOps::COP1_S_MOV() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); FixRoundModel(CRegInfo::RoundDefault); Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); } @@ -8226,7 +8298,7 @@ void CRecompilerOps::COP1_S_ROUND_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8238,7 +8310,7 @@ void CRecompilerOps::COP1_S_TRUNC_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8246,11 +8318,11 @@ void CRecompilerOps::COP1_S_TRUNC_L() ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundTruncate); } -void CRecompilerOps::COP1_S_CEIL_L() //added by Witten +void CRecompilerOps::COP1_S_CEIL_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8258,11 +8330,11 @@ void CRecompilerOps::COP1_S_CEIL_L() //added by Witten ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundUp); } -void CRecompilerOps::COP1_S_FLOOR_L() //added by Witten +void CRecompilerOps::COP1_S_FLOOR_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8274,7 +8346,7 @@ void CRecompilerOps::COP1_S_ROUND_W() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8286,7 +8358,7 @@ void CRecompilerOps::COP1_S_TRUNC_W() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8298,7 +8370,7 @@ void CRecompilerOps::COP1_S_CEIL_W() // added by Witten { // added by Witten CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8310,7 +8382,7 @@ void CRecompilerOps::COP1_S_FLOOR_W() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8322,7 +8394,7 @@ void CRecompilerOps::COP1_S_CVT_D() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8334,7 +8406,7 @@ void CRecompilerOps::COP1_S_CVT_W() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8346,7 +8418,7 @@ void CRecompilerOps::COP1_S_CVT_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Float)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float); @@ -8368,7 +8440,7 @@ void CRecompilerOps::COP1_S_CMP() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if ((m_Opcode.funct & 7) == 0) { CRecompilerOps::UnknownOpcode(); } if ((m_Opcode.funct & 2) != 0) { cmp |= 0x4000; } if ((m_Opcode.funct & 4) != 0) { cmp |= 0x0100; } @@ -8430,7 +8502,7 @@ void CRecompilerOps::COP1_D_ADD() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); if (RegInStack(Reg2, CRegInfo::FPU_Double)) @@ -8459,7 +8531,7 @@ void CRecompilerOps::COP1_D_SUB() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd == m_Opcode.ft) { @@ -8499,7 +8571,7 @@ void CRecompilerOps::COP1_D_MUL() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); FixRoundModel(CRegInfo::RoundDefault); Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double); @@ -8527,7 +8599,7 @@ void CRecompilerOps::COP1_D_DIV() CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd == m_Opcode.ft) { @@ -8588,7 +8660,7 @@ void CRecompilerOps::COP1_D_ROUND_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fs, true); @@ -8600,11 +8672,11 @@ void CRecompilerOps::COP1_D_ROUND_L() ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundNearest); } -void CRecompilerOps::COP1_D_TRUNC_L() //added by Witten +void CRecompilerOps::COP1_D_TRUNC_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fs, true); @@ -8616,11 +8688,11 @@ void CRecompilerOps::COP1_D_TRUNC_L() //added by Witten ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundTruncate); } -void CRecompilerOps::COP1_D_CEIL_L() //added by Witten +void CRecompilerOps::COP1_D_CEIL_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fs, true); @@ -8632,11 +8704,11 @@ void CRecompilerOps::COP1_D_CEIL_L() //added by Witten ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Qword, CRegInfo::RoundUp); } -void CRecompilerOps::COP1_D_FLOOR_L() //added by Witten +void CRecompilerOps::COP1_D_FLOOR_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fs, true); @@ -8652,7 +8724,7 @@ void CRecompilerOps::COP1_D_ROUND_W() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fs, true); @@ -8668,7 +8740,7 @@ void CRecompilerOps::COP1_D_TRUNC_W() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fd, true); @@ -8684,7 +8756,7 @@ void CRecompilerOps::COP1_D_CEIL_W() // added by Witten { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fs, true); @@ -8696,11 +8768,11 @@ void CRecompilerOps::COP1_D_CEIL_W() // added by Witten ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundUp); } -void CRecompilerOps::COP1_D_FLOOR_W() //added by Witten +void CRecompilerOps::COP1_D_FLOOR_W() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fs, true); @@ -8716,7 +8788,7 @@ void CRecompilerOps::COP1_D_CVT_S() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fd, true); @@ -8732,7 +8804,7 @@ void CRecompilerOps::COP1_D_CVT_W() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fs, true); @@ -8748,7 +8820,7 @@ void CRecompilerOps::COP1_D_CVT_L() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword)) { UnMap_FPR(m_Opcode.fs, true); @@ -8773,7 +8845,7 @@ void CRecompilerOps::COP1_D_CMP() } CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if ((m_Opcode.funct & 7) == 0) { CRecompilerOps::UnknownOpcode(); } if ((m_Opcode.funct & 2) != 0) { cmp |= 0x4000; } if ((m_Opcode.funct & 4) != 0) { cmp |= 0x0100; } @@ -8830,7 +8902,7 @@ void CRecompilerOps::COP1_W_CVT_S() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword); @@ -8842,7 +8914,7 @@ void CRecompilerOps::COP1_W_CVT_D() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword); @@ -8855,7 +8927,7 @@ void CRecompilerOps::COP1_L_CVT_S() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword); @@ -8867,7 +8939,7 @@ void CRecompilerOps::COP1_L_CVT_D() { CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); - m_Section->CompileCop1Test(); + CompileCop1Test(); if (m_Opcode.fd != m_Opcode.fs || !RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword)) { Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword); @@ -8936,12 +9008,775 @@ void CRecompilerOps::CompileExitCode() for (EXIT_LIST::iterator ExitIter = m_ExitInfo.begin(); ExitIter != m_ExitInfo.end(); ExitIter++) { CPU_Message(""); - CPU_Message(" $Exit_%d",ExitIter->ID); - SetJump32(ExitIter->JumpLoc,(uint32_t *)*g_RecompPos); + CPU_Message(" $Exit_%d", ExitIter->ID); + SetJump32(ExitIter->JumpLoc, (uint32_t *)*g_RecompPos); m_NextInstruction = ExitIter->NextInstruction; - CompileExit((uint32_t)-1, ExitIter->TargetPC,ExitIter->ExitRegSet,ExitIter->reason,true,NULL); + CompileExit((uint32_t)-1, ExitIter->TargetPC, ExitIter->ExitRegSet, ExitIter->reason, true, NULL); } } + +void CRecompilerOps::CompileCop1Test() +{ + if (m_RegWorkingSet.FpuBeenUsed()) + return; + + TestVariable(STATUS_CU1, &g_Reg->STATUS_REGISTER, "STATUS_REGISTER"); + CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::COP1_Unuseable, false, JeLabel32); + m_RegWorkingSet.FpuBeenUsed() = true; +} + +void CRecompilerOps::CompileInPermLoop(CRegInfo & RegSet, uint32_t ProgramCounter) +{ + MoveConstToVariable(ProgramCounter, _PROGRAM_COUNTER, "PROGRAM_COUNTER"); + RegSet.WriteBackRegisters(); + UpdateCounters(RegSet, false, true); + Call_Direct(AddressOf(CInterpreterCPU::InPermLoop), "CInterpreterCPU::InPermLoop"); + MoveConstToX86reg((uint32_t)g_SystemTimer, x86_ECX); + Call_Direct(AddressOf(&CSystemTimer::TimerDone), "CSystemTimer::TimerDone"); + CPU_Message("CompileSystemCheck 3"); + CompileSystemCheck((uint32_t)-1, RegSet); + if (g_SyncSystem) + { + MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX); + Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); + } +} + +bool CRecompilerOps::SetupRegisterForLoop(CCodeBlock * BlockInfo, const CRegInfo & RegSet) +{ + CRegInfo OriginalReg = m_RegWorkingSet; + if (!LoopAnalysis(BlockInfo, m_Section).SetupRegisterForLoop()) + { + return false; + } + for (int i = 1; i < 32; i++) + { + if (OriginalReg.GetMipsRegState(i) != RegSet.GetMipsRegState(i)) + { + UnMap_GPR(i, true); + } + } + return true; +} + +void CRecompilerOps::SyncRegState(const CRegInfo & SyncTo) +{ + ResetX86Protection(); + + bool changed = false; + UnMap_AllFPRs(); + if (m_RegWorkingSet.GetRoundingModel() != SyncTo.GetRoundingModel()) { m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); } + x86Reg MemStackReg = Get_MemoryStack(); + x86Reg TargetStackReg = SyncTo.Get_MemoryStack(); + + //CPU_Message("MemoryStack for Original State = %s",MemStackReg > 0?x86_Name(MemStackReg):"Not Mapped"); + if (MemStackReg != TargetStackReg) + { + if (TargetStackReg == x86_Unknown) + { + UnMap_X86reg(MemStackReg); + } + else if (MemStackReg == x86_Unknown) + { + UnMap_X86reg(TargetStackReg); + CPU_Message(" regcache: allocate %s as Memory Stack", x86_Name(TargetStackReg)); + m_RegWorkingSet.SetX86Mapped(TargetStackReg, CRegInfo::Stack_Mapped); + MoveVariableToX86reg(&g_Recompiler->MemoryStackPos(), "MemoryStack", TargetStackReg); + } + else + { + UnMap_X86reg(TargetStackReg); + CPU_Message(" regcache: change allocation of Memory Stack from %s to %s", x86_Name(MemStackReg), x86_Name(TargetStackReg)); + m_RegWorkingSet.SetX86Mapped(TargetStackReg, CRegInfo::Stack_Mapped); + m_RegWorkingSet.SetX86Mapped(MemStackReg, CRegInfo::NotMapped); + MoveX86RegToX86Reg(MemStackReg, TargetStackReg); + } + } + + for (int i = 1; i < 32; i++) + { + if (GetMipsRegState(i) == SyncTo.GetMipsRegState(i) || + (g_System->b32BitCore() && GetMipsRegState(i) == CRegInfo::STATE_MAPPED_32_ZERO && SyncTo.GetMipsRegState(i) == CRegInfo::STATE_MAPPED_32_SIGN) || + (g_System->b32BitCore() && GetMipsRegState(i) == CRegInfo::STATE_MAPPED_32_SIGN && SyncTo.GetMipsRegState(i) == CRegInfo::STATE_MAPPED_32_ZERO)) + { + switch (GetMipsRegState(i)) { + case CRegInfo::STATE_UNKNOWN: continue; + case CRegInfo::STATE_MAPPED_64: + if (GetMipsRegMapHi(i) == SyncTo.GetMipsRegMapHi(i) && + GetMipsRegMapLo(i) == SyncTo.GetMipsRegMapLo(i)) + { + continue; + } + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + case CRegInfo::STATE_MAPPED_32_SIGN: + if (GetMipsRegMapLo(i) == SyncTo.GetMipsRegMapLo(i)) + { + continue; + } + break; + case CRegInfo::STATE_CONST_64: + if (GetMipsReg(i) != SyncTo.GetMipsReg(i)) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + continue; + case CRegInfo::STATE_CONST_32_SIGN: + if (GetMipsRegLo(i) != SyncTo.GetMipsRegLo(i)) + { + CPU_Message("Value of const is different Reg %d (%s) Value: 0x%08X to 0x%08X", i, CRegName::GPR[i], GetMipsRegLo(i), SyncTo.GetMipsRegLo(i)); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + continue; + default: + CPU_Message("Unhandled Reg state %d\nin SyncRegState", GetMipsRegState(i)); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + changed = true; + + switch (SyncTo.GetMipsRegState(i)) + { + case CRegInfo::STATE_UNKNOWN: UnMap_GPR(i, true); break; + case CRegInfo::STATE_MAPPED_64: + { + x86Reg Reg = SyncTo.GetMipsRegMapLo(i); + x86Reg x86RegHi = SyncTo.GetMipsRegMapHi(i); + UnMap_X86reg(Reg); + UnMap_X86reg(x86RegHi); + switch (GetMipsRegState(i)) + { + case CRegInfo::STATE_UNKNOWN: + MoveVariableToX86reg(&_GPR[i].UW[0], CRegName::GPR_Lo[i], Reg); + MoveVariableToX86reg(&_GPR[i].UW[1], CRegName::GPR_Hi[i], x86RegHi); + break; + case CRegInfo::STATE_MAPPED_64: + MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); + MoveX86RegToX86Reg(GetMipsRegMapHi(i), x86RegHi); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapHi(i), CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_SIGN: + MoveX86RegToX86Reg(GetMipsRegMapLo(i), x86RegHi); + ShiftRightSignImmed(x86RegHi, 31); + MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + XorX86RegToX86Reg(x86RegHi, x86RegHi); + MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); + break; + case CRegInfo::STATE_CONST_64: + MoveConstToX86reg(GetMipsRegHi(i), x86RegHi); + MoveConstToX86reg(GetMipsRegLo(i), Reg); + break; + case CRegInfo::STATE_CONST_32_SIGN: + MoveConstToX86reg(GetMipsRegLo_S(i) >> 31, x86RegHi); + MoveConstToX86reg(GetMipsRegLo(i), Reg); + break; + default: + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_64\n%d", GetMipsRegState(i)); + g_Notify->BreakPoint(__FILE__, __LINE__); + continue; + } + m_RegWorkingSet.SetMipsRegMapLo(i, Reg); + m_RegWorkingSet.SetMipsRegMapHi(i, x86RegHi); + m_RegWorkingSet.SetMipsRegState(i, CRegInfo::STATE_MAPPED_64); + m_RegWorkingSet.SetX86Mapped(Reg, CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86Mapped(x86RegHi, CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86MapOrder(Reg, 1); + m_RegWorkingSet.SetX86MapOrder(x86RegHi, 1); + } + break; + case CRegInfo::STATE_MAPPED_32_SIGN: + { + x86Reg Reg = SyncTo.GetMipsRegMapLo(i); + UnMap_X86reg(Reg); + switch (GetMipsRegState(i)) + { + case CRegInfo::STATE_UNKNOWN: MoveVariableToX86reg(&_GPR[i].UW[0], CRegName::GPR_Lo[i], Reg); break; + case CRegInfo::STATE_CONST_32_SIGN: MoveConstToX86reg(GetMipsRegLo(i), Reg); break; + case CRegInfo::STATE_MAPPED_32_SIGN: + MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + if (GetMipsRegMapLo(i) != Reg) + { + MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); + } + break; + case CRegInfo::STATE_MAPPED_64: + MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapHi(i), CRegInfo::NotMapped); + break; + case CRegInfo::STATE_CONST_64: + CPU_Message("hi %X\nLo %X", GetMipsRegHi(i), GetMipsRegLo(i)); + default: + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_SIGN\n%d", GetMipsRegState(i)); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + m_RegWorkingSet.SetMipsRegMapLo(i, Reg); + m_RegWorkingSet.SetMipsRegState(i, CRegInfo::STATE_MAPPED_32_SIGN); + m_RegWorkingSet.SetX86Mapped(Reg, CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86MapOrder(Reg, 1); + } + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + { + x86Reg Reg = SyncTo.GetMipsRegMapLo(i); + UnMap_X86reg(Reg); + switch (GetMipsRegState(i)) + { + case CRegInfo::STATE_MAPPED_64: + case CRegInfo::STATE_UNKNOWN: + MoveVariableToX86reg(&_GPR[i].UW[0], CRegName::GPR_Lo[i], Reg); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_SIGN: + if (g_System->b32BitCore()) + { + MoveX86RegToX86Reg(GetMipsRegMapLo(i), Reg); + m_RegWorkingSet.SetX86Mapped(GetMipsRegMapLo(i), CRegInfo::NotMapped); + } + else + { + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d", GetMipsRegState(i)); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + break; + case CRegInfo::STATE_CONST_32_SIGN: + if (!g_System->b32BitCore() && GetMipsRegLo_S(i) < 0) + { + CPU_Message("Sign Problems in SyncRegState\nSTATE_MAPPED_32_ZERO"); + CPU_Message("%s: %X", CRegName::GPR[i], GetMipsRegLo_S(i)); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + MoveConstToX86reg(GetMipsRegLo(i), Reg); + break; + default: + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d", GetMipsRegState(i)); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + m_RegWorkingSet.SetMipsRegMapLo(i, Reg); + m_RegWorkingSet.SetMipsRegState(i, SyncTo.GetMipsRegState(i)); + m_RegWorkingSet.SetX86Mapped(Reg, CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86MapOrder(Reg, 1); + } + break; + default: + CPU_Message("%d - %d reg: %s (%d)", SyncTo.GetMipsRegState(i), GetMipsRegState(i), CRegName::GPR[i], i); + g_Notify->BreakPoint(__FILE__, __LINE__); + changed = false; + } + } +} + +CRegInfo & CRecompilerOps::GetRegWorkingSet(void) +{ + return m_RegWorkingSet; +} + +void CRecompilerOps::SetRegWorkingSet(const CRegInfo & RegInfo) +{ + m_RegWorkingSet = RegInfo; +} + +bool CRecompilerOps::InheritParentInfo() +{ + if (m_Section->m_CompiledLocation == NULL) + { + m_Section->m_CompiledLocation = *g_RecompPos; + m_Section->DisplaySectionInformation(); + m_Section->m_CompiledLocation = NULL; + } + else + { + m_Section->DisplaySectionInformation(); + } + + if (m_Section->m_ParentSection.empty()) + { + SetRegWorkingSet(m_Section->m_RegEnter); + return true; + } + + if (m_Section->m_ParentSection.size() == 1) + { + CCodeSection * Parent = *(m_Section->m_ParentSection.begin()); + if (Parent->m_CompiledLocation == NULL) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + CJumpInfo * JumpInfo = m_Section == Parent->m_ContinueSection ? &Parent->m_Cont : &Parent->m_Jump; + + m_Section->m_RegEnter = JumpInfo->RegSet; + LinkJump(*JumpInfo, m_Section->m_SectionID); + SetRegWorkingSet(m_Section->m_RegEnter); + return true; + } + + //Multiple Parents + BLOCK_PARENT_LIST ParentList; + CCodeSection::SECTION_LIST::iterator iter; + for (iter = m_Section->m_ParentSection.begin(); iter != m_Section->m_ParentSection.end(); iter++) + { + CCodeSection * Parent = *iter; + BLOCK_PARENT BlockParent; + + if (Parent->m_CompiledLocation == NULL) { continue; } + if (Parent->m_JumpSection != Parent->m_ContinueSection) + { + BlockParent.Parent = Parent; + BlockParent.JumpInfo = m_Section == Parent->m_ContinueSection ? &Parent->m_Cont : &Parent->m_Jump; + ParentList.push_back(BlockParent); + } + else + { + BlockParent.Parent = Parent; + BlockParent.JumpInfo = &Parent->m_Cont; + ParentList.push_back(BlockParent); + BlockParent.Parent = Parent; + BlockParent.JumpInfo = &Parent->m_Jump; + ParentList.push_back(BlockParent); + } + } + size_t NoOfCompiledParents = ParentList.size(); + if (NoOfCompiledParents == 0) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return false; + } + + // Add all the uncompiled blocks to the end of the list + for (iter = m_Section->m_ParentSection.begin(); iter != m_Section->m_ParentSection.end(); iter++) + { + CCodeSection * Parent = *iter; + BLOCK_PARENT BlockParent; + + if (Parent->m_CompiledLocation != NULL) { continue; } + if (Parent->m_JumpSection != Parent->m_ContinueSection) + { + BlockParent.Parent = Parent; + BlockParent.JumpInfo = m_Section == Parent->m_ContinueSection ? &Parent->m_Cont : &Parent->m_Jump; + ParentList.push_back(BlockParent); + } + else + { + BlockParent.Parent = Parent; + BlockParent.JumpInfo = &Parent->m_Cont; + ParentList.push_back(BlockParent); + BlockParent.Parent = Parent; + BlockParent.JumpInfo = &Parent->m_Jump; + ParentList.push_back(BlockParent); + } + } + int FirstParent = -1; + for (size_t i = 0; i < NoOfCompiledParents; i++) + { + if (!ParentList[i].JumpInfo->FallThrough) + { + continue; + } + if (FirstParent != -1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + FirstParent = i; + } + if (FirstParent == -1) + { + FirstParent = 0; + } + + //Link First Parent to start + CCodeSection * Parent = ParentList[FirstParent].Parent; + CJumpInfo * JumpInfo = ParentList[FirstParent].JumpInfo; + + SetRegWorkingSet(JumpInfo->RegSet); + m_RegWorkingSet.ResetX86Protection(); + LinkJump(*JumpInfo, m_Section->m_SectionID, Parent->m_SectionID); + + if (JumpInfo->ExitReason == CExitInfo::Normal_NoSysCheck) + { + if (JumpInfo->RegSet.GetBlockCycleCount() != 0) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (JumpInfo->JumpPC != (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + else + { + UpdateCounters(JumpInfo->RegSet, m_Section->m_EnterPC < JumpInfo->JumpPC, true); + if (JumpInfo->JumpPC == (uint32_t)-1) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (m_Section->m_EnterPC <= JumpInfo->JumpPC) + { + CPU_Message("CompileSystemCheck 10"); + CompileSystemCheck(m_Section->m_EnterPC, GetRegWorkingSet()); + } + } + JumpInfo->FallThrough = false; + + //Fix up initial state + UnMap_AllFPRs(); + + //determine loop reg usage + if (m_Section->m_InLoop && ParentList.size() > 1) + { + if (!SetupRegisterForLoop(m_Section->m_BlockInfo, m_Section->m_RegEnter)) { return false; } + m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); + } + + for (size_t i = 0; i < ParentList.size(); i++) + { + x86Reg MemoryStackPos; + int i2; + + if (i == (size_t)FirstParent) { continue; } + Parent = ParentList[i].Parent; + if (Parent->m_CompiledLocation == NULL) + { + continue; + } + CRegInfo * RegSet = &ParentList[i].JumpInfo->RegSet; + + if (m_RegWorkingSet.GetRoundingModel() != RegSet->GetRoundingModel()) { m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); } + + //Find Parent MapRegState + MemoryStackPos = x86_Unknown; + for (i2 = 0; i2 < sizeof(x86_Registers) / sizeof(x86_Registers[0]); i2++) + { + if (RegSet->GetX86Mapped(x86_Registers[i2]) == CRegInfo::Stack_Mapped) + { + MemoryStackPos = x86_Registers[i2]; + break; + } + } + if (MemoryStackPos == x86_Unknown) + { + // if the memory stack position is not mapped then unmap it + x86Reg MemStackReg = Get_MemoryStack(); + if (MemStackReg != x86_Unknown) + { + UnMap_X86reg(MemStackReg); + } + } + + for (i2 = 1; i2 < 32; i2++) + { + if (Is32BitMapped(i2)) + { + switch (RegSet->GetMipsRegState(i2)) + { + case CRegInfo::STATE_MAPPED_64: Map_GPR_64bit(i2, i2); break; + case CRegInfo::STATE_MAPPED_32_ZERO: break; + case CRegInfo::STATE_MAPPED_32_SIGN: + if (IsUnsigned(i2)) + { + m_RegWorkingSet.SetMipsRegState(i2, CRegInfo::STATE_MAPPED_32_SIGN); + } + break; + case CRegInfo::STATE_CONST_64: Map_GPR_64bit(i2, i2); break; + case CRegInfo::STATE_CONST_32_SIGN: + if ((RegSet->GetMipsRegLo_S(i2) < 0) && IsUnsigned(i2)) + { + m_RegWorkingSet.SetMipsRegState(i2, CRegInfo::STATE_MAPPED_32_SIGN); + } + break; + case CRegInfo::STATE_UNKNOWN: + if (g_System->b32BitCore()) + { + Map_GPR_32bit(i2, true, i2); + } + else + { + //Map_GPR_32bit(i2,true,i2); + Map_GPR_64bit(i2, i2); //?? + //UnMap_GPR(Section,i2,true); ?? + } + break; + default: + CPU_Message("Unknown CPU State(%d) in InheritParentInfo", GetMipsRegState(i2)); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + if (IsConst(i2)) { + if (GetMipsRegState(i2) != RegSet->GetMipsRegState(i2)) + { + switch (RegSet->GetMipsRegState(i2)) + { + case CRegInfo::STATE_MAPPED_64: + Map_GPR_64bit(i2, i2); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + if (Is32Bit(i2)) + { + Map_GPR_32bit(i2, (GetMipsRegLo(i2) & 0x80000000) != 0, i2); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + break; + case CRegInfo::STATE_MAPPED_32_SIGN: + if (Is32Bit(i2)) + { + Map_GPR_32bit(i2, true, i2); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + break; + case CRegInfo::STATE_UNKNOWN: + if (g_System->b32BitCore()) + { + Map_GPR_32bit(i2, true, i2); + } + else + { + Map_GPR_64bit(i2, i2); + } + break; + default: + CPU_Message("Unknown CPU State(%d) in InheritParentInfo", RegSet->GetMipsRegState(i2)); + g_Notify->BreakPoint(__FILE__, __LINE__); + break; + } + } + else if (Is32Bit(i2) && GetMipsRegLo(i2) != RegSet->GetMipsRegLo(i2)) + { + Map_GPR_32bit(i2, true, i2); + } + else if (Is64Bit(i2) && GetMipsReg(i2) != RegSet->GetMipsReg(i2)) + { + Map_GPR_32bit(i2, true, i2); + } + } + ResetX86Protection(); + } + + if (MemoryStackPos > 0) + { + Map_MemoryStack(MemoryStackPos, true); + } + } + m_Section->m_RegEnter = m_RegWorkingSet; + + //Sync registers for different blocks + stdstr_f Label("Section_%d", m_Section->m_SectionID); + int CurrentParent = FirstParent; + bool NeedSync = false; + for (size_t i = 0; i < NoOfCompiledParents; i++) + { + CRegInfo * RegSet; + int i2; + + if (i == (size_t)FirstParent) { continue; } + Parent = ParentList[i].Parent; + JumpInfo = ParentList[i].JumpInfo; + RegSet = &ParentList[i].JumpInfo->RegSet; + + if (JumpInfo->RegSet.GetBlockCycleCount() != 0) { NeedSync = true; } + + for (i2 = 0; !NeedSync && i2 < 8; i2++) + { + if (m_RegWorkingSet.FpuMappedTo(i2) == (uint32_t)-1) + { + NeedSync = true; + } + } + + for (i2 = 0; !NeedSync && i2 < sizeof(x86_Registers) / sizeof(x86_Registers[0]); i2++) + { + if (m_RegWorkingSet.GetX86Mapped(x86_Registers[i2]) == CRegInfo::Stack_Mapped) + { + if (m_RegWorkingSet.GetX86Mapped(x86_Registers[i2]) != RegSet->GetX86Mapped(x86_Registers[i2])) + { + NeedSync = true; + } + break; + } + } + for (i2 = 0; !NeedSync && i2 < 32; i2++) + { + if (NeedSync == true) { break; } + if (m_RegWorkingSet.GetMipsRegState(i2) != RegSet->GetMipsRegState(i2)) + { + NeedSync = true; + continue; + } + switch (m_RegWorkingSet.GetMipsRegState(i2)) + { + case CRegInfo::STATE_UNKNOWN: break; + case CRegInfo::STATE_MAPPED_64: + if (GetMipsRegMapHi(i2) != RegSet->GetMipsRegMapHi(i2) || + GetMipsRegMapLo(i2) != RegSet->GetMipsRegMapLo(i2)) + { + NeedSync = true; + } + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + case CRegInfo::STATE_MAPPED_32_SIGN: + if (GetMipsRegMapLo(i2) != RegSet->GetMipsRegMapLo(i2)) + { + //DisplayError(L"Parent: %d",Parent->SectionID); + NeedSync = true; + } + break; + case CRegInfo::STATE_CONST_32_SIGN: + if (GetMipsRegLo(i2) != RegSet->GetMipsRegLo(i2)) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + NeedSync = true; + } + break; + default: + WriteTrace(TraceRecompiler, TraceError, "Unhandled Reg state %d\nin InheritParentInfo", GetMipsRegState(i2)); + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + if (NeedSync == false) { continue; } + Parent = ParentList[CurrentParent].Parent; + JumpInfo = ParentList[CurrentParent].JumpInfo; + JmpLabel32(Label.c_str(), 0); + JumpInfo->LinkLocation = (uint32_t *)(*g_RecompPos - 4); + JumpInfo->LinkLocation2 = NULL; + + CurrentParent = i; + Parent = ParentList[CurrentParent].Parent; + JumpInfo = ParentList[CurrentParent].JumpInfo; + CPU_Message(" Section_%d (from %d):", m_Section->m_SectionID, Parent->m_SectionID); + if (JumpInfo->LinkLocation != NULL) + { + SetJump32(JumpInfo->LinkLocation, (uint32_t *)*g_RecompPos); + JumpInfo->LinkLocation = NULL; + if (JumpInfo->LinkLocation2 != NULL) + { + SetJump32(JumpInfo->LinkLocation2, (uint32_t *)*g_RecompPos); + JumpInfo->LinkLocation2 = NULL; + } + } + + m_RegWorkingSet = JumpInfo->RegSet; + if (m_Section->m_EnterPC < JumpInfo->JumpPC) + { + UpdateCounters(m_RegWorkingSet, true, true); + CPU_Message("CompileSystemCheck 11"); + CompileSystemCheck(m_Section->m_EnterPC, m_RegWorkingSet); + } + else + { + UpdateCounters(m_RegWorkingSet, false, true); + } + SyncRegState(m_Section->m_RegEnter); //Sync + m_Section->m_RegEnter = m_RegWorkingSet; + } + + for (size_t i = 0; i < NoOfCompiledParents; i++) + { + Parent = ParentList[i].Parent; + JumpInfo = ParentList[i].JumpInfo; + LinkJump(*JumpInfo); + } + + CPU_Message(" Section_%d:", m_Section->m_SectionID); + m_Section->m_RegEnter.SetBlockCycleCount(0); + return true; +} + +void CRecompilerOps::LinkJump(CJumpInfo & JumpInfo, uint32_t SectionID, uint32_t FromSectionID) +{ + if (JumpInfo.LinkLocation != NULL) + { + if (SectionID != -1) + { + if (FromSectionID != -1) + { + CPU_Message(" Section_%d (from %d):", SectionID, FromSectionID); + } + else + { + CPU_Message(" Section_%d:", SectionID); + } + } + SetJump32(JumpInfo.LinkLocation, (uint32_t *)*g_RecompPos); + JumpInfo.LinkLocation = NULL; + if (JumpInfo.LinkLocation2 != NULL) + { + SetJump32(JumpInfo.LinkLocation2, (uint32_t *)*g_RecompPos); + JumpInfo.LinkLocation2 = NULL; + } + } +} + +void CRecompilerOps::JumpToSection(CCodeSection * Section) +{ + char Label[100]; + sprintf(Label, "Section_%d", Section->m_SectionID); + JmpLabel32(Label, 0); + SetJump32(((uint32_t *)*g_RecompPos) - 1, (uint32_t *)(Section->m_CompiledLocation)); +} + +void CRecompilerOps::JumpToUnknown(CJumpInfo * JumpInfo) +{ + JmpLabel32(JumpInfo->BranchLabel.c_str(), 0); + JumpInfo->LinkLocation = (uint32_t*)(*g_RecompPos - 4); +} + +void CRecompilerOps::SetCurrentPC(uint32_t ProgramCounter) +{ + m_CompilePC = ProgramCounter; + __except_try() + { + if (!g_MMU->LW_VAddr(m_CompilePC, m_Opcode.Hex)) + { + g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD)); + } + } + __except_catch() + { + g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION)); + } +} + +uint32_t CRecompilerOps::GetCurrentPC(void) +{ + return m_CompilePC; +} + +void CRecompilerOps::SetCurrentSection(CCodeSection * section) +{ + m_Section = section; +} + +void CRecompilerOps::SetNextStepType(STEP_TYPE StepType) +{ + m_NextInstruction = StepType; +} + +STEP_TYPE CRecompilerOps::GetNextStepType(void) +{ + return m_NextInstruction; +} + +const OPCODE & CRecompilerOps::GetOpcode(void) const +{ + return m_Opcode; +} + void CRecompilerOps::UpdateSyncCPU(CRegInfo & RegSet, uint32_t Cycles) { if (!g_SyncSystem) @@ -9056,6 +9891,11 @@ void CRecompilerOps::OverflowDelaySlot(bool TestTimer) m_NextInstruction = END_BLOCK; } +void CRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason, bool CompileNow) +{ + CompileExit(JumpPC, TargetPC, ExitRegSet, reason, CompileNow, NULL); +} + void CRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason, bool CompileNow, void(*x86Jmp)(const char * Label, uint32_t Value)) { if (!CompileNow) @@ -9309,6 +10149,57 @@ void CRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &E } } +void CRecompilerOps::Compile_StoreInstructClean(x86Reg AddressReg, int32_t Length) +{ + if (!g_System->bSMM_StoreInstruc()) + { + return; + } + g_Notify->BreakPoint(__FILE__, __LINE__); + + /* + stdstr_f strLen("%d",Length); + UnMap_AllFPRs(); + + /*x86Reg StoreTemp1 = Map_TempReg(x86_Any,-1,false); + MoveX86RegToX86Reg(AddressReg, StoreTemp1); + AndConstToX86Reg(StoreTemp1,0xFFC);*/ + BeforeCallDirect(m_RegWorkingSet); + PushImm32("CRecompiler::Remove_StoreInstruc", CRecompiler::Remove_StoreInstruc); + PushImm32(Length); + Push(AddressReg); + MoveConstToX86reg((uint32_t)g_Recompiler, x86_ECX); + Call_Direct(AddressOf(&CRecompiler::ClearRecompCode_Virt), "CRecompiler::ClearRecompCode_Virt"); + AfterCallDirect(m_RegWorkingSet); + /*JmpLabel8("MemCheckDone",0); + uint8_t * MemCheckDone = *g_RecompPos - 1; + + CPU_Message(" "); + CPU_Message(" NotDelaySlot:"); + SetJump8(NotDelaySlotJump,*g_RecompPos); + + MoveX86RegToX86Reg(AddressReg, StoreTemp1); + ShiftRightUnsignImmed(StoreTemp1,12); + LeaRegReg(StoreTemp1,StoreTemp1,(uint32_t)&(g_Recompiler->FunctionTable()[0]),Multip_x4); + CompConstToX86regPointer(StoreTemp1,0); + JeLabel8("MemCheckDone",0); + uint8_t * MemCheckDone2 = *g_RecompPos - 1; + + BeforeCallDirect(m_RegWorkingSet); + PushImm32("CRecompiler::Remove_StoreInstruc",CRecompiler::Remove_StoreInstruc); + PushImm32(strLen.c_str(),Length); + Push(AddressReg); + MoveConstToX86reg((uint32_t)g_Recompiler,x86_ECX); + Call_Direct(AddressOf(&CRecompiler::ClearRecompCode_Virt), "CRecompiler::ClearRecompCode_Virt"); + AfterCallDirect(m_RegWorkingSet); + + CPU_Message(" "); + CPU_Message(" MemCheckDone:"); + SetJump8(MemCheckDone,*g_RecompPos); + SetJump8(MemCheckDone2,*g_RecompPos); + + X86Protected(StoreTemp1) = false;*/ +} void CRecompilerOps::SB_Const(uint8_t Value, uint32_t VAddr) { @@ -9425,7 +10316,7 @@ void CRecompilerOps::SH_Const(uint16_t Value, uint32_t VAddr) return; } - if (!g_TransVaddr->TranslateVaddr(VAddr, PAddr)) + if (!g_TransVaddr->TranslateVaddr(VAddr, PAddr)) { CPU_Message("%s\nFailed to translate address: %08X", __FUNCTION__, VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) @@ -9593,18 +10484,18 @@ void CRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr) AfterCallDirect(m_RegWorkingSet); break; case 0x04040010: - { - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + { + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + UpdateCounters(m_RegWorkingSet, false, true); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); - BeforeCallDirect(m_RegWorkingSet); - PushImm32(Value); - PushImm32(PAddr); - MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); - Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); - AfterCallDirect(m_RegWorkingSet); - } + BeforeCallDirect(m_RegWorkingSet); + PushImm32(Value); + PushImm32(PAddr); + MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); + Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); + AfterCallDirect(m_RegWorkingSet); + } break; case 0x0404001C: MoveConstToVariable(0, &g_Reg->SP_SEMAPHORE_REG, "SP_SEMAPHORE_REG"); break; case 0x04080000: MoveConstToVariable(Value & 0xFFC, &g_Reg->SP_PC_REG, "SP_PC_REG"); break; @@ -9636,113 +10527,113 @@ void CRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr) case 0x04300000: switch (PAddr) { - case 0x04300000: - { - uint32_t ModValue; - ModValue = 0x7F; - if ((Value & MI_CLR_INIT) != 0) - { - ModValue |= MI_MODE_INIT; - } - if ((Value & MI_CLR_EBUS) != 0) - { - ModValue |= MI_MODE_EBUS; - } - if ((Value & MI_CLR_RDRAM) != 0) - { - ModValue |= MI_MODE_RDRAM; - } - if (ModValue != 0) - { - AndConstToVariable(~ModValue, &g_Reg->MI_MODE_REG, "MI_MODE_REG"); - } + case 0x04300000: + { + uint32_t ModValue; + ModValue = 0x7F; + if ((Value & MI_CLR_INIT) != 0) + { + ModValue |= MI_MODE_INIT; + } + if ((Value & MI_CLR_EBUS) != 0) + { + ModValue |= MI_MODE_EBUS; + } + if ((Value & MI_CLR_RDRAM) != 0) + { + ModValue |= MI_MODE_RDRAM; + } + if (ModValue != 0) + { + AndConstToVariable(~ModValue, &g_Reg->MI_MODE_REG, "MI_MODE_REG"); + } - ModValue = (Value & 0x7F); - if ((Value & MI_SET_INIT) != 0) - { - ModValue |= MI_MODE_INIT; - } - if ((Value & MI_SET_EBUS) != 0) - { - ModValue |= MI_MODE_EBUS; - } - if ((Value & MI_SET_RDRAM) != 0) - { - ModValue |= MI_MODE_RDRAM; - } - if (ModValue != 0) { - OrConstToVariable(ModValue, &g_Reg->MI_MODE_REG, "MI_MODE_REG"); - } - if ((Value & MI_CLR_DP_INTR) != 0) - { - AndConstToVariable((uint32_t)~MI_INTR_DP, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); - AndConstToVariable((uint32_t)~MI_INTR_DP, &g_Reg->m_GfxIntrReg, "m_GfxIntrReg"); - } - } + ModValue = (Value & 0x7F); + if ((Value & MI_SET_INIT) != 0) + { + ModValue |= MI_MODE_INIT; + } + if ((Value & MI_SET_EBUS) != 0) + { + ModValue |= MI_MODE_EBUS; + } + if ((Value & MI_SET_RDRAM) != 0) + { + ModValue |= MI_MODE_RDRAM; + } + if (ModValue != 0) { + OrConstToVariable(ModValue, &g_Reg->MI_MODE_REG, "MI_MODE_REG"); + } + if ((Value & MI_CLR_DP_INTR) != 0) + { + AndConstToVariable((uint32_t)~MI_INTR_DP, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); + AndConstToVariable((uint32_t)~MI_INTR_DP, &g_Reg->m_GfxIntrReg, "m_GfxIntrReg"); + } + } break; case 0x0430000C: - { - uint32_t ModValue; - ModValue = 0; - if ((Value & MI_INTR_MASK_CLR_SP) != 0) - { - ModValue |= MI_INTR_MASK_SP; - } - if ((Value & MI_INTR_MASK_CLR_SI) != 0) - { - ModValue |= MI_INTR_MASK_SI; - } - if ((Value & MI_INTR_MASK_CLR_AI) != 0) - { - ModValue |= MI_INTR_MASK_AI; - } - if ((Value & MI_INTR_MASK_CLR_VI) != 0) - { - ModValue |= MI_INTR_MASK_VI; - } - if ((Value & MI_INTR_MASK_CLR_PI) != 0) - { - ModValue |= MI_INTR_MASK_PI; - } - if ((Value & MI_INTR_MASK_CLR_DP) != 0) - { - ModValue |= MI_INTR_MASK_DP; - } - if (ModValue != 0) - { - AndConstToVariable(~ModValue, &g_Reg->MI_INTR_MASK_REG, "MI_INTR_MASK_REG"); - } + { + uint32_t ModValue; + ModValue = 0; + if ((Value & MI_INTR_MASK_CLR_SP) != 0) + { + ModValue |= MI_INTR_MASK_SP; + } + if ((Value & MI_INTR_MASK_CLR_SI) != 0) + { + ModValue |= MI_INTR_MASK_SI; + } + if ((Value & MI_INTR_MASK_CLR_AI) != 0) + { + ModValue |= MI_INTR_MASK_AI; + } + if ((Value & MI_INTR_MASK_CLR_VI) != 0) + { + ModValue |= MI_INTR_MASK_VI; + } + if ((Value & MI_INTR_MASK_CLR_PI) != 0) + { + ModValue |= MI_INTR_MASK_PI; + } + if ((Value & MI_INTR_MASK_CLR_DP) != 0) + { + ModValue |= MI_INTR_MASK_DP; + } + if (ModValue != 0) + { + AndConstToVariable(~ModValue, &g_Reg->MI_INTR_MASK_REG, "MI_INTR_MASK_REG"); + } - ModValue = 0; - if ((Value & MI_INTR_MASK_SET_SP) != 0) - { - ModValue |= MI_INTR_MASK_SP; - } - if ((Value & MI_INTR_MASK_SET_SI) != 0) - { - ModValue |= MI_INTR_MASK_SI; - } - if ((Value & MI_INTR_MASK_SET_AI) != 0) - { - ModValue |= MI_INTR_MASK_AI; - } - if ((Value & MI_INTR_MASK_SET_VI) != 0) - { - ModValue |= MI_INTR_MASK_VI; - } - if ((Value & MI_INTR_MASK_SET_PI) != 0) - { - ModValue |= MI_INTR_MASK_PI; - } - if ((Value & MI_INTR_MASK_SET_DP) != 0) - { - ModValue |= MI_INTR_MASK_DP; - } - if (ModValue != 0) - { - OrConstToVariable(ModValue, &g_Reg->MI_INTR_MASK_REG, "MI_INTR_MASK_REG"); - } - } + ModValue = 0; + if ((Value & MI_INTR_MASK_SET_SP) != 0) + { + ModValue |= MI_INTR_MASK_SP; + } + if ((Value & MI_INTR_MASK_SET_SI) != 0) + { + ModValue |= MI_INTR_MASK_SI; + } + if ((Value & MI_INTR_MASK_SET_AI) != 0) + { + ModValue |= MI_INTR_MASK_AI; + } + if ((Value & MI_INTR_MASK_SET_VI) != 0) + { + ModValue |= MI_INTR_MASK_VI; + } + if ((Value & MI_INTR_MASK_SET_PI) != 0) + { + ModValue |= MI_INTR_MASK_PI; + } + if ((Value & MI_INTR_MASK_SET_DP) != 0) + { + ModValue |= MI_INTR_MASK_DP; + } + if (ModValue != 0) + { + OrConstToVariable(ModValue, &g_Reg->MI_INTR_MASK_REG, "MI_INTR_MASK_REG"); + } + } break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) @@ -9950,18 +10841,18 @@ void CRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr) } break; case 0x1fc00000: - { - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); - UpdateCounters(m_RegWorkingSet, false, true); - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + { + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + UpdateCounters(m_RegWorkingSet, false, true); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); - BeforeCallDirect(m_RegWorkingSet); - PushImm32(Value); - PushImm32(PAddr); - MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); - Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); - AfterCallDirect(m_RegWorkingSet); - } + BeforeCallDirect(m_RegWorkingSet); + PushImm32(Value); + PushImm32(PAddr); + MoveConstToX86reg((uint32_t)(g_MMU), x86_ECX); + Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); + AfterCallDirect(m_RegWorkingSet); + } break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h index 632c99c4f..6c5ecf444 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h @@ -15,10 +15,12 @@ #include #include #include +#include #include #include #include +class CCodeBlock; class CCodeSection; class CRecompilerOps : @@ -61,19 +63,19 @@ public: void COP1_BCT_Compare(); /************************* OpCode functions *************************/ - static void J (); + void J (); void JAL (); - static void ADDI (); - static void ADDIU (); - static void SLTI (); - static void SLTIU (); - static void ANDI (); - static void ORI (); - static void XORI (); - static void LUI (); - static void DADDIU (); - static void LDL (); - static void LDR (); + void ADDI (); + void ADDIU (); + void SLTI (); + void SLTIU (); + void ANDI (); + void ORI (); + void XORI (); + void LUI (); + void DADDIU (); + void LDL (); + void LDR (); void LB (); void LH (); void LWL (); @@ -87,9 +89,9 @@ public: void SWL (); void SW (); void SWR (); - static void SDL (); - static void SDR (); - static void CACHE (); + void SDL (); + void SDR (); + void CACHE (); void LL (); void LWC1 (); void LDC1 (); @@ -100,131 +102,151 @@ public: void SD (); /********************** R4300i OpCodes: Special **********************/ - static void SPECIAL_SLL (); - static void SPECIAL_SRL (); - static void SPECIAL_SRA (); - static void SPECIAL_SLLV (); - static void SPECIAL_SRLV (); - static void SPECIAL_SRAV (); + void SPECIAL_SLL (); + void SPECIAL_SRL (); + void SPECIAL_SRA (); + void SPECIAL_SLLV (); + void SPECIAL_SRLV (); + void SPECIAL_SRAV (); void SPECIAL_JR (); void SPECIAL_JALR (); void SPECIAL_SYSCALL(); - static void SPECIAL_MFLO (); - static void SPECIAL_MTLO (); - static void SPECIAL_MFHI (); - static void SPECIAL_MTHI (); - static void SPECIAL_DSLLV (); - static void SPECIAL_DSRLV (); - static void SPECIAL_DSRAV (); - static void SPECIAL_MULT (); - static void SPECIAL_MULTU (); + void SPECIAL_MFLO (); + void SPECIAL_MTLO (); + void SPECIAL_MFHI (); + void SPECIAL_MTHI (); + void SPECIAL_DSLLV (); + void SPECIAL_DSRLV (); + void SPECIAL_DSRAV (); + void SPECIAL_MULT (); + void SPECIAL_MULTU (); void SPECIAL_DIV (); - static void SPECIAL_DIVU (); - static void SPECIAL_DMULT (); - static void SPECIAL_DMULTU (); - static void SPECIAL_DDIV (); - static void SPECIAL_DDIVU (); - static void SPECIAL_ADD (); - static void SPECIAL_ADDU (); - static void SPECIAL_SUB (); - static void SPECIAL_SUBU (); - static void SPECIAL_AND (); - static void SPECIAL_OR (); - static void SPECIAL_XOR (); - static void SPECIAL_NOR (); - static void SPECIAL_SLT (); - static void SPECIAL_SLTU (); - static void SPECIAL_DADD (); - static void SPECIAL_DADDU (); - static void SPECIAL_DSUB (); - static void SPECIAL_DSUBU (); - static void SPECIAL_DSLL (); - static void SPECIAL_DSRL (); - static void SPECIAL_DSRA (); - static void SPECIAL_DSLL32 (); - static void SPECIAL_DSRL32 (); - static void SPECIAL_DSRA32 (); + void SPECIAL_DIVU (); + void SPECIAL_DMULT (); + void SPECIAL_DMULTU (); + void SPECIAL_DDIV (); + void SPECIAL_DDIVU (); + void SPECIAL_ADD (); + void SPECIAL_ADDU (); + void SPECIAL_SUB (); + void SPECIAL_SUBU (); + void SPECIAL_AND (); + void SPECIAL_OR (); + void SPECIAL_XOR (); + void SPECIAL_NOR (); + void SPECIAL_SLT (); + void SPECIAL_SLTU (); + void SPECIAL_DADD (); + void SPECIAL_DADDU (); + void SPECIAL_DSUB (); + void SPECIAL_DSUBU (); + void SPECIAL_DSLL (); + void SPECIAL_DSRL (); + void SPECIAL_DSRA (); + void SPECIAL_DSLL32 (); + void SPECIAL_DSRL32 (); + void SPECIAL_DSRA32 (); /************************** COP0 functions **************************/ - static void COP0_MF (); - static void COP0_MT (); + void COP0_MF (); + void COP0_MT (); /************************** COP0 CO functions ***********************/ - static void COP0_CO_TLBR (); - static void COP0_CO_TLBWI (); - static void COP0_CO_TLBWR (); - static void COP0_CO_TLBP (); + void COP0_CO_TLBR (); + void COP0_CO_TLBWI (); + void COP0_CO_TLBWR (); + void COP0_CO_TLBP (); void COP0_CO_ERET (); /************************** COP1 functions **************************/ - static void COP1_MF (); - static void COP1_DMF (); - static void COP1_CF (); - static void COP1_MT (); - static void COP1_DMT (); - static void COP1_CT (); + void COP1_MF (); + void COP1_DMF (); + void COP1_CF (); + void COP1_MT (); + void COP1_DMT (); + void COP1_CT (); /************************** COP1: S functions ************************/ - static void COP1_S_ADD (); - static void COP1_S_SUB (); - static void COP1_S_MUL (); - static void COP1_S_DIV (); - static void COP1_S_ABS (); - static void COP1_S_NEG (); - static void COP1_S_SQRT (); - static void COP1_S_MOV (); - static void COP1_S_ROUND_L (); - static void COP1_S_TRUNC_L (); - static void COP1_S_CEIL_L (); - static void COP1_S_FLOOR_L (); - static void COP1_S_ROUND_W (); - static void COP1_S_TRUNC_W (); - static void COP1_S_CEIL_W (); - static void COP1_S_FLOOR_W (); - static void COP1_S_CVT_D (); - static void COP1_S_CVT_W (); - static void COP1_S_CVT_L (); - static void COP1_S_CMP (); + void COP1_S_ADD (); + void COP1_S_SUB (); + void COP1_S_MUL (); + void COP1_S_DIV (); + void COP1_S_ABS (); + void COP1_S_NEG (); + void COP1_S_SQRT (); + void COP1_S_MOV (); + void COP1_S_ROUND_L (); + void COP1_S_TRUNC_L (); + void COP1_S_CEIL_L (); + void COP1_S_FLOOR_L (); + void COP1_S_ROUND_W (); + void COP1_S_TRUNC_W (); + void COP1_S_CEIL_W (); + void COP1_S_FLOOR_W (); + void COP1_S_CVT_D (); + void COP1_S_CVT_W (); + void COP1_S_CVT_L (); + void COP1_S_CMP (); /************************** COP1: D functions ************************/ - static void COP1_D_ADD (); - static void COP1_D_SUB (); - static void COP1_D_MUL (); - static void COP1_D_DIV (); - static void COP1_D_ABS (); - static void COP1_D_NEG (); - static void COP1_D_SQRT (); - static void COP1_D_MOV (); - static void COP1_D_ROUND_L (); - static void COP1_D_TRUNC_L (); - static void COP1_D_CEIL_L (); - static void COP1_D_FLOOR_L (); - static void COP1_D_ROUND_W (); - static void COP1_D_TRUNC_W (); - static void COP1_D_CEIL_W (); - static void COP1_D_FLOOR_W (); - static void COP1_D_CVT_S (); - static void COP1_D_CVT_W (); - static void COP1_D_CVT_L (); - static void COP1_D_CMP (); + void COP1_D_ADD (); + void COP1_D_SUB (); + void COP1_D_MUL (); + void COP1_D_DIV (); + void COP1_D_ABS (); + void COP1_D_NEG (); + void COP1_D_SQRT (); + void COP1_D_MOV (); + void COP1_D_ROUND_L (); + void COP1_D_TRUNC_L (); + void COP1_D_CEIL_L (); + void COP1_D_FLOOR_L (); + void COP1_D_ROUND_W (); + void COP1_D_TRUNC_W (); + void COP1_D_CEIL_W (); + void COP1_D_FLOOR_W (); + void COP1_D_CVT_S (); + void COP1_D_CVT_W (); + void COP1_D_CVT_L (); + void COP1_D_CMP (); /************************** COP1: W functions ************************/ - static void COP1_W_CVT_S (); - static void COP1_W_CVT_D (); + void COP1_W_CVT_S (); + void COP1_W_CVT_D (); /************************** COP1: L functions ************************/ - static void COP1_L_CVT_S (); - static void COP1_L_CVT_D (); + void COP1_L_CVT_S (); + void COP1_L_CVT_D (); /************************** Other functions **************************/ - static void UnknownOpcode (); + void UnknownOpcode (); - void CompileExitCode(); - static void BeforeCallDirect(CRegInfo & RegSet); - static void AfterCallDirect(CRegInfo & RegSet); static void EnterCodeBlock(); static void ExitCodeBlock(); + void CompileExitCode(); + void CompileCop1Test(); + void CompileInPermLoop(CRegInfo & RegSet, uint32_t ProgramCounter); + void SyncRegState(const CRegInfo & SyncTo); + bool SetupRegisterForLoop(CCodeBlock * BlockInfo, const CRegInfo & RegSet); + CRegInfo & GetRegWorkingSet(void); + static void BeforeCallDirect(CRegInfo & RegSet); + static void AfterCallDirect(CRegInfo & RegSet); + void SetRegWorkingSet(const CRegInfo & RegInfo); + bool InheritParentInfo(); + void LinkJump(CJumpInfo & JumpInfo, uint32_t SectionID = -1, uint32_t FromSectionID = -1); + void JumpToSection(CCodeSection * Section); + void JumpToUnknown(CJumpInfo * JumpInfo); + void SetCurrentPC(uint32_t ProgramCounter); + uint32_t GetCurrentPC(void); + void SetCurrentSection(CCodeSection * section); + void SetNextStepType(STEP_TYPE StepType); + STEP_TYPE GetNextStepType( void ); + const OPCODE & GetOpcode ( void ) const; + void PreCompileOpcode(void); + void PostCompileOpcode ( void ); void Compile_StoreInstructClean(x86Reg AddressReg, int32_t Length); + void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason, bool CompileNow); + void CompileReadTLBMiss(uint32_t VirtualAddress, x86Reg LookUpReg); void CompileReadTLBMiss(x86Reg AddressReg, x86Reg LookUpReg); void CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg); @@ -234,12 +256,6 @@ public: static void ChangeDefaultRoundingModel(); static void OverflowDelaySlot(bool TestTimer); - static STEP_TYPE m_NextInstruction; - static uint32_t m_CompilePC; - static OPCODE m_Opcode; - static CX86RegInfo m_RegWorkingSet; - static uint32_t m_BranchCompare; - static CCodeSection * m_Section; /********* Helper Functions *********/ typedef CRegInfo::REG_STATE REG_STATE; @@ -350,9 +366,6 @@ public: public: static uint32_t CompilePC() { return m_CompilePC; } -protected: - void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason, bool CompileNow, void(*x86Jmp)(const char * Label, uint32_t Value)); - private: void SB_Const(uint8_t Value, uint32_t Addr); void SB_Register(CX86Ops::x86Reg Reg, uint32_t Addr); @@ -365,7 +378,14 @@ private: void LW_KnownAddress(x86Reg Reg, uint32_t VAddr); void LW(bool ResultSigned, bool bRecordLLBit); void SW(bool bCheckLLbit); + void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason, bool CompileNow, void(*x86Jmp)(const char * Label, uint32_t Value)); EXIT_LIST m_ExitInfo; + static STEP_TYPE m_NextInstruction; + static uint32_t m_CompilePC; + static OPCODE m_Opcode; + static CX86RegInfo m_RegWorkingSet; + static uint32_t m_BranchCompare; + static CCodeSection * m_Section; static uint32_t m_TempValue; };