From f92a2c67bacb0c3d9adc2a62c8bb8e5afd931f9b Mon Sep 17 00:00:00 2001 From: zilmar Date: Fri, 23 Jul 2010 10:45:35 +0000 Subject: [PATCH] git-svn-id: https://localhost/svn/Project64/trunk@43 111125ac-702d-7242-af9c-5ba8ae61c1ef --- .../N64 System/Mips/Memory Virtual Mem.cpp | 49 +- .../N64 System/Mips/Memory Virtual Mem.h | 1 - Source/Project64/N64 System/N64 Class.cpp | 51 +- .../N64 System/Recompiler/Code Block.h | 6 +- .../N64 System/Recompiler/Code Section.cpp | 1481 ++++++++++++++++- .../N64 System/Recompiler/Code Section.h | 29 +- .../Recompiler/Recompiler Class.cpp | 1139 +------------ .../N64 System/Recompiler/Recompiler Class.h | 12 +- .../N64 System/Recompiler/Recompiler Ops.cpp | 67 +- .../N64 System/Recompiler/Recompiler Ops.h | 7 +- .../N64 System/Recompiler/Reg Info.cpp | 276 +-- .../N64 System/Recompiler/Reg Info.h | 20 +- .../N64 System/Recompiler/Section Info.cpp | 79 +- .../N64 System/Recompiler/Section Info.h | 1 - .../N64 System/Speed Limitor Class.cpp | 8 +- Source/Project64/Settings.h | 4 +- .../Project64/Settings/N64System Settings.cpp | 8 +- .../Project64/Settings/N64System Settings.h | 4 +- .../Settings/Recompiler Settings.cpp | 4 + .../Project64/Settings/Recompiler Settings.h | 28 +- Source/Project64/Settings/Settings Class.cpp | 4 +- .../Settings Page - Game - Recompiler.cpp | 2 +- .../Settings Page - Game - Recompiler.h | 2 +- .../Project64/User Interface/UI Resources.aps | Bin 306572 -> 306572 bytes .../Project64/User Interface/UI Resources.rc | 12 +- Source/Project64/User Interface/resource.h | 2 +- 26 files changed, 1783 insertions(+), 1513 deletions(-) diff --git a/Source/Project64/N64 System/Mips/Memory Virtual Mem.cpp b/Source/Project64/N64 System/Mips/Memory Virtual Mem.cpp index 772815ea0..42514fafe 100644 --- a/Source/Project64/N64 System/Mips/Memory Virtual Mem.cpp +++ b/Source/Project64/N64 System/Mips/Memory Virtual Mem.cpp @@ -1256,28 +1256,25 @@ void CMipsMemoryVM::Compile_SW_Register (x86Reg Reg, DWORD VAddr ) void CMipsMemoryVM::ResetMemoryStack ( void) { - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix x86Reg Reg, TempReg; CPU_Message(" ResetMemoryStack"); - x86reg = Map_MemoryStack(Section, x86_Any, false); - if (x86reg >= 0) { UnMap_X86reg(Section,x86reg); } + Reg = Map_MemoryStack( x86_Any, false); + if (Reg >= 0) { UnMap_X86reg(Reg); } - x86reg = Map_TempReg(x86_Any, 29, FALSE); + Reg = Map_TempReg(x86_Any, 29, FALSE); if (_Settings->LoadBool(Game_UseTlb)) { TempReg = Map_TempReg(x86_Any,-1,FALSE); - MoveX86RegToX86Reg(x86reg,TempReg); + MoveX86RegToX86Reg(Reg,TempReg); ShiftRightUnsignImmed(TempReg,12); MoveVariableDispToX86Reg(m_TLB_ReadMap,"m_TLB_ReadMap",TempReg,TempReg,4); - AddX86RegToX86Reg(x86reg,TempReg); + AddX86RegToX86Reg(Reg,TempReg); } else { - AndConstToX86Reg(x86reg,0x1FFFFFFF); - AddConstToX86Reg(x86reg,(DWORD)m_RDRAM); + AndConstToX86Reg(Reg,0x1FFFFFFF); + AddConstToX86Reg(Reg,(DWORD)m_RDRAM); } - MoveX86regToVariable(x86reg, g_MemoryStack, "MemoryStack"); -#endif + MoveX86regToVariable(Reg,&(_Recompiler->MemoryStackPos()), "MemoryStack"); } int CMipsMemoryVM::MemoryFilter( DWORD dwExptCode, void * lpExceptionPointer ) @@ -2517,16 +2514,14 @@ void CMipsMemoryVM::Compile_LW (void) if (Opcode.rt == 0) return; x86Reg TempReg1, TempReg2; -#ifdef tofix - if (Opcode.base == 29 && SPHack) { + if (Opcode.base == 29 && bFastSP()) { char String[100]; Map_GPR_32bit(Opcode.rt,TRUE,-1); TempReg1 = Map_MemoryStack(x86_Any,true); sprintf(String,"%Xh",(short)Opcode.offset); - MoveVariableDispToX86Reg((void *)((DWORD)(short)Opcode.offset),String,cMipsRegLo(Opcode.rt),TempReg1,1); + MoveVariableDispToX86Reg((void *)((DWORD)(short)Opcode.offset),String,cMipsRegMapLo(Opcode.rt),TempReg1,1); } else { -#endif if (IsConst(Opcode.base)) { DWORD Address = cMipsRegLo(Opcode.base) + (short)Opcode.offset; Map_GPR_32bit(Opcode.rt,TRUE,-1); @@ -2575,14 +2570,15 @@ void CMipsMemoryVM::Compile_LW (void) MoveN64MemToX86reg(cMipsRegMapLo(Opcode.rt),cMipsRegMapLo(Opcode.rt)); } } -#ifdef tofix } - if (SPHack && Opcode.rt == 29) + if (bFastSP() && Opcode.rt == 29) { +_Notify->BreakPoint(__FILE__,__LINE__); +#ifdef tofix ResetX86Protection(); _MMU->ResetMemoryStack(m_Section); - } #endif + } } void CMipsMemoryVM::Compile_LWC1 (void) @@ -2852,7 +2848,7 @@ void CMipsMemoryVM::Compile_LD (void) Compile_LW(cMipsRegMapHi(Opcode.rt),Address); Compile_LW(cMipsRegMapLo(Opcode.rt),Address + 4); #ifdef tofix - if (SPHack && Opcode.rt == 29) { _MMU->ResetMemoryStack(m_Section); } + if (bFastSP() && Opcode.rt == 29) { _MMU->ResetMemoryStack(m_Section); } #endif return; } @@ -2895,12 +2891,11 @@ void CMipsMemoryVM::Compile_LD (void) MoveN64MemToX86reg(cMipsRegMapHi(Opcode.rt),TempReg1); MoveN64MemDispToX86reg(cMipsRegMapLo(Opcode.rt),TempReg1,4); } -#ifdef tofix - if (SPHack && Opcode.rt == 29) { + if (bFastSP() && Opcode.rt == 29) + { ResetX86Protection(); - _MMU->ResetMemoryStack(m_Section); + _MMU->ResetMemoryStack(); } -#endif } void CMipsMemoryVM::Compile_LDC1 (void) @@ -3156,21 +3151,19 @@ void CMipsMemoryVM::Compile_SW (void) CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(Opcode.Hex,m_CompilePC)); x86Reg TempReg1, TempReg2; -#ifdef tofix - if (Opcode.base == 29 && SPHack) { + if (Opcode.base == 29 && bFastSP()) { if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } TempReg1 = Map_MemoryStack(x86_Any,true); if (IsConst(Opcode.rt)) { MoveConstToMemoryDisp (cMipsRegLo(Opcode.rt),TempReg1, (DWORD)((short)Opcode.offset)); } else if (IsMapped(Opcode.rt)) { - MoveX86regToMemory(cMipsRegLo(Opcode.rt),TempReg1,(DWORD)((short)Opcode.offset)); + MoveX86regToMemory(cMipsRegMapLo(Opcode.rt),TempReg1,(DWORD)((short)Opcode.offset)); } else { TempReg2 = Map_TempReg(x86_Any,Opcode.rt,FALSE); MoveX86regToMemory(TempReg2,TempReg1,(DWORD)((short)Opcode.offset)); } } else { -#endif if (IsConst(Opcode.base)) { DWORD Address = cMipsRegLo(Opcode.base) + (short)Opcode.offset; @@ -3224,9 +3217,7 @@ void CMipsMemoryVM::Compile_SW (void) MoveX86regToN64Mem(Map_TempReg(x86_Any,Opcode.rt,FALSE),TempReg1); } } -#ifdef tofix } -#endif } void CMipsMemoryVM::Compile_SWC1 (void) diff --git a/Source/Project64/N64 System/Mips/Memory Virtual Mem.h b/Source/Project64/N64 System/Mips/Memory Virtual Mem.h index 6670c6cdf..7bf933635 100644 --- a/Source/Project64/N64 System/Mips/Memory Virtual Mem.h +++ b/Source/Project64/N64 System/Mips/Memory Virtual Mem.h @@ -24,7 +24,6 @@ class CMipsMemoryVM : //Current Half line void UpdateHalfLine ( void ); DWORD m_HalfLine; - DWORD m_MemoryStack; DWORD m_TempValue; //Initilizing and reseting information about the memory system diff --git a/Source/Project64/N64 System/N64 Class.cpp b/Source/Project64/N64 System/N64 Class.cpp index 8056eb6ef..3abde8e39 100644 --- a/Source/Project64/N64 System/N64 Class.cpp +++ b/Source/Project64/N64 System/N64 Class.cpp @@ -798,8 +798,8 @@ void CN64System::ExecuteInterpret (CC_Core & C_Core) { void CN64System::ExecuteRecompiler (CC_Core & C_Core) { //execute opcodes while no errors - m_Recomp = new CRecompiler(m_Profile,m_EndEmulation); InitializeCPUCore(); + m_Recomp = new CRecompiler(m_Profile,m_EndEmulation); SetActiveSystem(); m_Recomp->Run(); } @@ -912,23 +912,20 @@ void CN64System::SyncCPU (CN64System * const SecondCPU) { if (m_Reg.m_HI.DW != SecondCPU->m_Reg.m_HI.DW) { ErrorFound = true; } if (m_Reg.m_LO.DW != SecondCPU->m_Reg.m_LO.DW) { ErrorFound = true; } - for (int z = 0; z < 0x100; z++) + /*for (int z = 0; z < 0x100; z++) { if (m_MMU_VM.Rdram()[0x00206970 + z] != SecondCPU->m_MMU_VM.Rdram()[0x00206970 + z]) { ErrorFound = true; } - } + }*/ - if (bSPHack()) + if (bFastSP() && m_Recomp) { - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - if (_MMU->m_MemoryStack != (DWORD)(RDRAM + (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF))) + if (m_Recomp->MemoryStackPos() != (DWORD)(m_MMU_VM.Rdram() + (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF))) { ErrorFound = true; } -#endif } if (m_SystemTimer.CurrentType() != SecondCPU->m_SystemTimer.CurrentType()) { ErrorFound = true; } @@ -1010,15 +1007,12 @@ void CN64System::DumpSyncErrors (CN64System * SecondCPU) { { Error.LogF("RoundingModel: %X %X\r\n",m_Reg.m_RoundingModel,SecondCPU->m_Reg.m_RoundingModel); } - if (_Settings->LoadBool(Game_SPHack)) + if (bFastSP() && m_Recomp) { - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - if (_MMU->m_MemoryStack != (DWORD)(RDRAM + (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF))) + if (m_Recomp->MemoryStackPos() != (DWORD)(m_MMU_VM.Rdram() + (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF))) { - Error.LogF("MemoryStack = %X should be: %X\r\n",_MMU->m_MemoryStack, (DWORD)(_MMU->RDRAM + (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF))); + Error.LogF("MemoryStack = %X should be: %X\r\n",m_Recomp->MemoryStackPos(), (DWORD)(m_MMU_VM.Rdram() + (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF))); } -#endif } Error.Log("\r\n"); Error.Log("Information:\r\n"); @@ -1347,10 +1341,10 @@ bool CN64System::LoadState(LPCSTR FileName) { unzReadCurrentFile(file,m_Reg.m_RDRAM_Interface,sizeof(DWORD)*8); unzReadCurrentFile(file,m_Reg.m_SerialInterface,sizeof(DWORD)*4); unzReadCurrentFile(file,(void *const)&_TLB->TlbEntry(0),sizeof(CTLB::TLB_ENTRY)*32); - unzReadCurrentFile(file,_MMU->PifRam(),0x40); - unzReadCurrentFile(file,_MMU->Rdram(),SaveRDRAMSize); - unzReadCurrentFile(file,_MMU->Dmem(),0x1000); - unzReadCurrentFile(file,_MMU->Imem(),0x1000); + unzReadCurrentFile(file,m_MMU_VM.PifRam(),0x40); + unzReadCurrentFile(file,m_MMU_VM.Rdram(),SaveRDRAMSize); + unzReadCurrentFile(file,m_MMU_VM.Dmem(),0x1000); + unzReadCurrentFile(file,m_MMU_VM.Imem(),0x1000); unzCloseCurrentFile(file); unzClose(file); LoadedZipFile = true; @@ -1377,8 +1371,8 @@ bool CN64System::LoadState(LPCSTR FileName) { if (result == IDNO) { return FALSE; } } Reset(false,true); - _MMU->UnProtectMemory(0x80000000,0x80000000 + _Settings->LoadDword(Game_RDRamSize) - 4); - _MMU->UnProtectMemory(0xA4000000,0xA4001FFC); + m_MMU_VM.UnProtectMemory(0x80000000,0x80000000 + _Settings->LoadDword(Game_RDRamSize) - 4); + m_MMU_VM.UnProtectMemory(0xA4000000,0xA4001FFC); _Settings->SaveDword(Game_RDRamSize,SaveRDRAMSize); ReadFile( hSaveFile,&NextVITimer,sizeof(NextVITimer),&dwRead,NULL); @@ -1398,14 +1392,11 @@ bool CN64System::LoadState(LPCSTR FileName) { ReadFile( hSaveFile,m_Reg.m_Peripheral_Interface,sizeof(DWORD)*13,&dwRead,NULL); ReadFile( hSaveFile,m_Reg.m_RDRAM_Interface,sizeof(DWORD)*8,&dwRead,NULL); ReadFile( hSaveFile,m_Reg.m_SerialInterface,sizeof(DWORD)*4,&dwRead,NULL); - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - ReadFile( hSaveFile,_MMU->tlb,sizeof(TLB)*32,&dwRead,NULL); - ReadFile( hSaveFile,_MMU->PIF_Ram,0x40,&dwRead,NULL); -#endif - ReadFile( hSaveFile,_MMU->Rdram(),SaveRDRAMSize,&dwRead,NULL); - ReadFile( hSaveFile,_MMU->Dmem(),0x1000,&dwRead,NULL); - ReadFile( hSaveFile,_MMU->Imem(),0x1000,&dwRead,NULL); + ReadFile( hSaveFile,(void *const)&_TLB->TlbEntry(0),sizeof(CTLB::TLB_ENTRY)*32,&dwRead,NULL); + ReadFile( hSaveFile,m_MMU_VM.PifRam(),0x40,&dwRead,NULL); + ReadFile( hSaveFile,m_MMU_VM.Rdram(),SaveRDRAMSize,&dwRead,NULL); + ReadFile( hSaveFile,m_MMU_VM.Dmem(),0x1000,&dwRead,NULL); + ReadFile( hSaveFile,m_MMU_VM.Imem(),0x1000,&dwRead,NULL); CloseHandle(hSaveFile); } @@ -1433,9 +1424,7 @@ bool CN64System::LoadState(LPCSTR FileName) { #ifdef TEST_SP_TRACKING m_CurrentSP = GPR[29].UW[0]; #endif -#ifdef tofix - _MMU->m_MemoryStack = (DWORD)(_MMU->Rdram() + (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF)); -#endif + if (bFastSP() && m_Recomp) { m_Recomp->ResetMemoryStackPos(); } if (_Settings->LoadDword(Game_CpuType) == CPU_SyncCores) { if (m_SyncCPU) diff --git a/Source/Project64/N64 System/Recompiler/Code Block.h b/Source/Project64/N64 System/Recompiler/Code Block.h index 0d1c0bb8e..3163b4fe0 100644 --- a/Source/Project64/N64 System/Recompiler/Code Block.h +++ b/Source/Project64/N64 System/Recompiler/Code Block.h @@ -19,10 +19,14 @@ public: inline void SetVAddrFirst ( DWORD VAddr ) { m_VAddrFirst = VAddr; } inline void SetVAddrLast ( DWORD VAddr ) { m_VAddrLast = VAddr; } + inline void IncSectionCount ( void ) { m_NoOfSections += 1; } + + CCodeSection * ExistingSection ( DWORD Addr ) { return m_EnterSection.ExistingSection(Addr,NextTest()); } + EXIT_LIST m_ExitInfo; private: - void AnalyseBlock ( void ); + bool AnalyseBlock ( void ); void CompileExitCode ( void ); DWORD m_VAddrEnter; diff --git a/Source/Project64/N64 System/Recompiler/Code Section.cpp b/Source/Project64/N64 System/Recompiler/Code Section.cpp index de19cfecc..c43de46e1 100644 --- a/Source/Project64/N64 System/Recompiler/Code Section.cpp +++ b/Source/Project64/N64 System/Recompiler/Code Section.cpp @@ -83,13 +83,10 @@ CCodeSection::CCodeSection( CCodeBlock * CodeBlock, DWORD EnterPC, DWORD ID) : m_LinkAllowed(true), m_CompiledLocation(NULL), m_DelaySlotSection(CodeBlock? CodeBlock->bDelaySlot() : false), - m_Test(0) + m_Test(0), + m_Test2(0), + m_InLoop(false) { - /* - Test2 = 0; - InLoop = false; - - */ if (&CodeBlock->EnterSection() == this) { m_LinkAllowed = false; @@ -270,7 +267,7 @@ void CCodeSection::CompileExit ( DWORD JumpPC, DWORD TargetPC, CRegInfo ExitRegS case CExitInfo::ExitResetRecompCode: _Notify->BreakPoint(__FILE__,__LINE__); #ifdef tofix - if (NextInstruction == JUMP || NextInstruction == DELAY_SLOT) { + if (m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT) { X86BreakPoint(__FILE__,__LINE__); } if (_SyncSystem) { Call_Direct(SyncSystem, "SyncSystem"); } @@ -283,7 +280,7 @@ void CCodeSection::CompileExit ( DWORD JumpPC, DWORD TargetPC, CRegInfo ExitRegS case CExitInfo::TLBReadMiss: _Notify->BreakPoint(__FILE__,__LINE__); #ifdef tofix - MoveConstToX86reg(NextInstruction == JUMP || NextInstruction == DELAY_SLOT,x86_ECX); + MoveConstToX86reg(m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT,x86_ECX); MoveVariableToX86reg(&TLBLoadAddress,"TLBLoadAddress",x86_EDX); Call_Direct(DoTLBMiss,"DoTLBMiss"); if (_SyncSystem) { Call_Direct(SyncSystem, "SyncSystem"); } @@ -329,7 +326,7 @@ void CCodeSection::GenerateSectionLinkage (void) } } - if ((CRecompilerOps::CompilePC() & 0xFFC) == 0xFFC) { + if ((CompilePC() & 0xFFC) == 0xFFC) { //Handle Fall througth BYTE * Jump = NULL; for (count = 0; count < 2; count ++) { @@ -368,13 +365,13 @@ void CCodeSection::GenerateSectionLinkage (void) CPU_Message(" $FinishBlock:"); SetJump8(Jump,m_RecompPos); } - //MoveConstToVariable(CRecompilerOps::CompilePC() + 4,_PROGRAM_COUNTER,"PROGRAM_COUNTER"); + //MoveConstToVariable(CompilePC() + 4,_PROGRAM_COUNTER,"PROGRAM_COUNTER"); m_RegWorkingSet.WriteBackRegisters(); UpdateCounters(m_RegWorkingSet,false,true); // WriteBackRegisters(Section); // if (_SyncSystem) { Call_Direct(SyncSystem, "SyncSystem"); } - // MoveConstToVariable(DELAY_SLOT,&NextInstruction,"NextInstruction"); - PushImm32(stdstr_f("0x%08X",CRecompilerOps::CompilePC() + 4).c_str(),CRecompilerOps::CompilePC() + 4); + // MoveConstToVariable(DELAY_SLOT,&m_NextInstruction,"m_NextInstruction"); + PushImm32(stdstr_f("0x%08X",CompilePC() + 4).c_str(),CompilePC() + 4); // check if there is an existing section @@ -386,8 +383,8 @@ void CCodeSection::GenerateSectionLinkage (void) } if (!g_UseLinking) { if (CRecompilerOps::m_CompilePC == m_Jump.TargetPC && (m_Cont.FallThrough == false)) { - if (!DelaySlotEffectsJump(CRecompilerOps::CompilePC())) { - MoveConstToVariable(CRecompilerOps::CompilePC(),_PROGRAM_COUNTER,"PROGRAM_COUNTER"); + if (!DelaySlotEffectsJump(CompilePC())) { + MoveConstToVariable(CompilePC(),_PROGRAM_COUNTER,"PROGRAM_COUNTER"); m_RegWorkingSet.WriteBackRegisters(); UpdateCounters(m_RegWorkingSet,false, true); Call_Direct(InPermLoop,"InPermLoop"); @@ -415,7 +412,7 @@ _Notify->BreakPoint(__FILE__,__LINE__); JumpInfo[count]->LinkLocation2 = NULL; } } - CompileExit (CRecompilerOps::CompilePC(), JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet,CExitInfo::Normal,true,NULL); + CompileExit (CompilePC(), JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet,CExitInfo::Normal,true,NULL); JumpInfo[count]->FallThrough = false; } else if (TargetSection[count] != NULL && JumpInfo[count] != NULL) { if (!JumpInfo[count]->FallThrough) { continue; } @@ -428,7 +425,7 @@ _Notify->BreakPoint(__FILE__,__LINE__); JumpInfo[count]->LinkLocation2 = NULL; } } - CompileExit (CRecompilerOps::CompilePC(), JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet,CExitInfo::Normal,true,NULL); + CompileExit (CompilePC(), JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet,CExitInfo::Normal,true,NULL); //FreeSection(TargetSection[count],Section); } } @@ -459,7 +456,7 @@ _Notify->BreakPoint(__FILE__,__LINE__); JumpInfo[count]->LinkLocation2 = NULL; } } - if (JumpInfo[count]->TargetPC <= CRecompilerOps::CompilePC()) { + if (JumpInfo[count]->TargetPC <= CompilePC()) { if (JumpInfo[count]->PermLoop) { CPU_Message("PermLoop *** 1"); _Notify->BreakPoint(__FILE__,__LINE__); @@ -473,11 +470,7 @@ _Notify->BreakPoint(__FILE__,__LINE__); CompileSystemCheck(-1,JumpInfo[count]->RegSet); #endif } else { - _Notify->BreakPoint(__FILE__,__LINE__); - #ifdef tofix - UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(), &JumpInfo[count]->RegSet.BlockRandomModifier(), true); - CompileSystemCheck(JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet); - #endif + UpdateCounters(JumpInfo[count]->RegSet,true,true); } } else { _Notify->BreakPoint(__FILE__,__LINE__); @@ -489,8 +482,8 @@ _Notify->BreakPoint(__FILE__,__LINE__); #ifdef tofix JumpInfo[count]->RegSet.BlockCycleCount() = 0; m_RegWorkingSet = JumpInfo[count]->RegSet; - SyncRegState(Section,&TargetSection[count]->RegStart); #endif + SyncRegState(TargetSection[count]->m_RegEnter); JmpLabel32(Label,0); SetJump32((DWORD *)m_RecompPos - 1,(DWORD *)(TargetSection[count]->m_CompiledLocation)); } @@ -500,15 +493,16 @@ _Notify->BreakPoint(__FILE__,__LINE__); for (count = 0; count < 2; count ++) { if (TargetSection[count] == NULL) { continue; } - _Notify->BreakPoint(__FILE__,__LINE__); - #ifdef tofix - if (TargetSection[count]->ParentSection.empty()) { continue; } - for (SECTION_LIST::iterator iter = TargetSection[count]->ParentSection.begin(); iter != TargetSection[count]->ParentSection.end(); iter++) + if (TargetSection[count]->m_ParentSection.empty()) { continue; } + for (SECTION_LIST::iterator iter = TargetSection[count]->m_ParentSection.begin(); iter != TargetSection[count]->m_ParentSection.end(); iter++) { CCodeSection * Parent = *iter; - if (Parent->CompiledLocation != NULL) { continue; } - if (JumpInfo[count]->PermLoop) { + if (Parent->m_CompiledLocation != NULL) { continue; } + if (JumpInfo[count]->PermLoop) + { + _Notify->BreakPoint(__FILE__,__LINE__); +#ifdef tofix CPU_Message("PermLoop *** 2"); MoveConstToVariable(JumpInfo[count]->TargetPC,_PROGRAM_COUNTER,"PROGRAM_COUNTER"); JumpInfo[count]->RegSet.BlockCycleCount() -= g_CountPerOp; @@ -517,19 +511,19 @@ _Notify->BreakPoint(__FILE__,__LINE__); JumpInfo[count]->RegSet.BlockCycleCount() += g_CountPerOp; UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), true); CompileSystemCheck(-1,JumpInfo[count]->RegSet); +#endif } if (JumpInfo[count]->FallThrough) { JumpInfo[count]->FallThrough = false; - JmpLabel32(JumpInfo[count]->BranchLabel,0); - JumpInfo[count]->LinkLocation = m_RecompPos - 4; + JmpLabel32(JumpInfo[count]->BranchLabel.c_str(),0); + JumpInfo[count]->LinkLocation = (DWORD*)(m_RecompPos - 4); } } - #endif } for (count = 0; count < 2; count ++) { if (JumpInfo[count]->FallThrough) { - if (JumpInfo[count]->TargetPC < CRecompilerOps::CompilePC()) { + if (JumpInfo[count]->TargetPC < CompilePC()) { _Notify->BreakPoint(__FILE__,__LINE__); #ifdef tofix UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(),true); @@ -558,18 +552,16 @@ _Notify->BreakPoint(__FILE__,__LINE__); SetJump32(JumpInfo[count]->LinkLocation2,(DWORD *)m_RecompPos); JumpInfo[count]->LinkLocation2 = NULL; } - CompileExit (CRecompilerOps::CompilePC(),JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet,CExitInfo::Normal,true,NULL); + CompileExit (CompilePC(),JumpInfo[count]->TargetPC,JumpInfo[count]->RegSet,CExitInfo::Normal,true,NULL); continue; } if (JumpInfo[count]->TargetPC != TargetSection[count]->m_EnterPC) { DisplayError("I need to add more code in GenerateSectionLinkage cause this is going to cause an exception"); BreakPoint(__FILE__,__LINE__); } - if (TargetSection[count]->m_CompiledLocation == NULL) { - _Notify->BreakPoint(__FILE__,__LINE__); - #ifdef tofix - GenerateX86Code(*TargetSection[count]->m_BlockInfo,TargetSection[count],m_BlockInfo->m_Test + 1); - #endif + if (TargetSection[count]->m_CompiledLocation == NULL) + { + TargetSection[count]->GenerateX86Code(m_BlockInfo->NextTest()); } else { char Label[100]; @@ -581,7 +573,7 @@ _Notify->BreakPoint(__FILE__,__LINE__); JumpInfo[count]->LinkLocation2 = NULL; } m_RegWorkingSet = JumpInfo[count]->RegSet; - if (JumpInfo[count]->TargetPC <= CRecompilerOps::CompilePC()) { + if (JumpInfo[count]->TargetPC <= CompilePC()) { _Notify->BreakPoint(__FILE__,__LINE__); #ifdef tofix UpdateCounters(&JumpInfo[count]->RegSet.BlockCycleCount(),&JumpInfo[count]->RegSet.BlockRandomModifier(), true); @@ -602,16 +594,217 @@ _Notify->BreakPoint(__FILE__,__LINE__); #endif } m_RegWorkingSet = JumpInfo[count]->RegSet; - _Notify->BreakPoint(__FILE__,__LINE__); - #ifdef tofix - SyncRegState(Section,&TargetSection[count]->RegStart); - #endif + SyncRegState(TargetSection[count]->m_RegEnter); JmpLabel32(Label,0); SetJump32((DWORD *)m_RecompPos - 1,(DWORD *)(TargetSection[count]->m_CompiledLocation)); } } } +void CCodeSection::SyncRegState ( const CRegInfo & SyncTo ) +{ + x86Reg Reg, x86RegHi; + int count; + + bool changed = false; + UnMap_AllFPRs(); + if (m_RegWorkingSet.GetRoundingModel() != SyncTo.GetRoundingModel()) { m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); } + Reg = Map_MemoryStack(x86_Any, false); + //CPU_Message("MemoryStack for Original State = %s",x86Reg > 0?x86_Name(x86Reg):"Not Mapped"); + + for (Reg = (x86Reg)0; Reg < 10; Reg = (x86Reg)((int)Reg + 1)) + { + if (m_RegWorkingSet.GetX86Mapped(Reg) != CRegInfo::Stack_Mapped) { continue; } + if (SyncTo.GetX86Mapped(Reg) != CRegInfo::Stack_Mapped) { + UnMap_X86reg(Reg); + for (count = 0; count < 10; count ++) { + if (SyncTo.GetX86Mapped((x86Reg)count) == CRegInfo::Stack_Mapped) { + MoveX86RegToX86Reg((x86Reg)count,Reg); + changed = true; + } + } + if (!changed) + { + MoveVariableToX86reg(&_Recompiler->MemoryStackPos(),"MemoryStack",Reg); + } + changed = true; + } + } + for (Reg = (x86Reg)0; Reg < 10; Reg = (x86Reg)((int)Reg + 1)) + { + if (SyncTo.GetX86Mapped((x86Reg)Reg) != CRegInfo::Stack_Mapped) { continue; } + //CPU_Message("MemoryStack for Sync State = %s",x86Reg > 0?x86_Name(x86Reg):"Not Mapped"); + if (m_RegWorkingSet.GetX86Mapped((x86Reg)Reg) == CRegInfo::Stack_Mapped) { break; } + UnMap_X86reg((x86Reg)Reg); + } + + for (count = 1; count < 32; count ++) { + if (cMipsRegState(count) == SyncTo.cMipsRegState(count)) { + switch (cMipsRegState(count)) { + case CRegInfo::STATE_UNKNOWN: continue; + case CRegInfo::STATE_MAPPED_64: + if (MipsReg(count) == SyncTo.cMipsReg(count)) { + continue; + } + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + case CRegInfo::STATE_MAPPED_32_SIGN: + if (MipsRegLo(count) == SyncTo.cMipsRegLo(count)) { + continue; + } + break; + case CRegInfo::STATE_CONST_64: + if (MipsReg(count) != SyncTo.cMipsReg(count)) { +#if (!defined(EXTERNAL_RELEASE)) + DisplayError("Umm.. how ???"); +#endif + } + continue; + case CRegInfo::STATE_CONST_32: + if (MipsRegLo(count) != SyncTo.cMipsRegLo(count)) { +#if (!defined(EXTERNAL_RELEASE)) + DisplayError("Umm.. how ???"); +#endif + } + continue; +#ifndef EXTERNAL_RELEASE + default: + DisplayError("Unhandled Reg state %d\nin SyncRegState",MipsRegState(count)); +#endif + } + } + changed = true; + + switch (SyncTo.cMipsRegState(count)) { + case CRegInfo::STATE_UNKNOWN: UnMap_GPR(count,true); break; + case CRegInfo::STATE_MAPPED_64: + Reg = SyncTo.cMipsRegMapLo(count); + x86RegHi = SyncTo.cMipsRegMapHi(count); + UnMap_X86reg(Reg); + UnMap_X86reg(x86RegHi); + switch (MipsRegState(count)) { + case CRegInfo::STATE_UNKNOWN: + MoveVariableToX86reg(&_GPR[count].UW[0],CRegName::GPR_Lo[count],Reg); + MoveVariableToX86reg(&_GPR[count].UW[1],CRegName::GPR_Hi[count],x86RegHi); + break; + case CRegInfo::STATE_MAPPED_64: + MoveX86RegToX86Reg(MipsRegMapLo(count),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(count),CRegInfo::NotMapped); + MoveX86RegToX86Reg(MipsRegMapHi(count),x86RegHi); + m_RegWorkingSet.SetX86Mapped(MipsRegMapHi(count),CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_SIGN: + MoveX86RegToX86Reg(MipsRegMapLo(count),x86RegHi); + ShiftRightSignImmed(x86RegHi,31); + MoveX86RegToX86Reg(MipsRegMapLo(count),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(count),CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + XorX86RegToX86Reg(x86RegHi,x86RegHi); + MoveX86RegToX86Reg(MipsRegMapLo(count),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(count), CRegInfo::NotMapped); + break; + case CRegInfo::STATE_CONST_64: + MoveConstToX86reg(MipsRegHi(count),x86RegHi); + MoveConstToX86reg(MipsRegLo(count),Reg); + break; + case CRegInfo::STATE_CONST_32: + MoveConstToX86reg(MipsRegLo_S(count) >> 31,x86RegHi); + MoveConstToX86reg(MipsRegLo(count),Reg); + break; + default: +#ifndef EXTERNAL_RELEASE + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_64\n%d",MipsRegState(count)); + DisplayError("Do something with states in SyncRegState\nSTATE_MAPPED_64\n%d",MipsRegState(count)); +#endif + continue; + } + MipsRegLo(count) = Reg; + MipsRegHi(count) = x86RegHi; + MipsRegState(count) = 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: + Reg = SyncTo.cMipsRegMapLo(count); + UnMap_X86reg(Reg); + switch (MipsRegState(count)) { + case CRegInfo::STATE_UNKNOWN: MoveVariableToX86reg(&_GPR[count].UW[0],CRegName::GPR_Lo[count],Reg); break; + case CRegInfo::STATE_CONST_32: MoveConstToX86reg(MipsRegLo(count),Reg); break; + case CRegInfo::STATE_MAPPED_32_SIGN: + MoveX86RegToX86Reg(MipsRegMapLo(count),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(count),CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + if (MipsRegLo(count) != (DWORD)Reg) { + MoveX86RegToX86Reg(MipsRegMapLo(count),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(count),CRegInfo::NotMapped); + } + break; + case CRegInfo::STATE_MAPPED_64: + MoveX86RegToX86Reg(MipsRegMapLo(count),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(count),CRegInfo::NotMapped) ; + m_RegWorkingSet.SetX86Mapped(MipsRegMapHi(count),CRegInfo::NotMapped); + break; +#ifndef EXTERNAL_RELEASE + case CRegInfo::STATE_CONST_64: + DisplayError("hi %X\nLo %X",MipsRegHi(count),MipsRegLo(count)); + default: + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_SIGN\n%d",MipsRegState(count)); + DisplayError("Do something with states in SyncRegState\nSTATE_MAPPED_32_SIGN\n%d",MipsRegState(count)); +#endif + } + MipsRegLo(count) = Reg; + MipsRegState(count) = CRegInfo::STATE_MAPPED_32_SIGN; + m_RegWorkingSet.SetX86Mapped(Reg,CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86MapOrder(Reg,1); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + Reg = SyncTo.cMipsRegMapLo(count); + UnMap_X86reg(Reg); + switch (MipsRegState(count)) { + case CRegInfo::STATE_MAPPED_64: + case CRegInfo::STATE_UNKNOWN: + MoveVariableToX86reg(&_GPR[count].UW[0],CRegName::GPR_Lo[count],Reg); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + MoveX86RegToX86Reg(MipsRegMapLo(count),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(count),CRegInfo::NotMapped); + break; + case CRegInfo::STATE_CONST_32: + if (MipsRegLo_S(count) < 0) { + CPU_Message("Sign Problems in SyncRegState\nSTATE_MAPPED_32_ZERO"); + CPU_Message("%s: %X",CRegName::GPR[count],MipsRegLo_S(count)); +#ifndef EXTERNAL_RELEASE + DisplayError("Sign Problems in SyncRegState\nSTATE_MAPPED_32_ZERO"); +#endif + } + MoveConstToX86reg(MipsRegLo(count),Reg); + break; +#ifndef EXTERNAL_RELEASE + default: + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d",MipsRegState(count)); + DisplayError("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d",MipsRegState(count)); +#endif + } + MipsRegLo(count) = Reg; + MipsRegState(count) = SyncTo.cMipsRegState(count); + m_RegWorkingSet.SetX86Mapped(Reg,CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86MapOrder(Reg,1); + break; + default: +#if (!defined(EXTERNAL_RELEASE)) + CPU_Message("%d\n%d\nreg: %s (%d)",SyncTo.cMipsRegState(count),MipsRegState(count),CRegName::GPR[count],count); + DisplayError("%d\n%d\nreg: %s (%d)",SyncTo.cMipsRegState(count),MipsRegState(count),CRegName::GPR[count],count); + DisplayError("Do something with states in SyncRegState"); +#endif + changed = false; + } + } +} + void CCodeSection::CompileCop1Test (void) { if (m_RegWorkingSet.FpuBeenUsed()) { return; } TestVariable(STATUS_CU1,&_Reg->STATUS_REGISTER,"STATUS_REGISTER"); @@ -619,6 +812,83 @@ void CCodeSection::CompileCop1Test (void) { m_RegWorkingSet.FpuBeenUsed() = TRUE; } +bool CCodeSection::CreateSectionLinkage ( void ) +{ + InheritConstants(); + + if (!FillSectionInfo(NORMAL)) + { + return false; + } + + CCodeSection ** TargetSection[2]; + CJumpInfo * JumpInfo[2]; + if (m_Jump.TargetPC < m_Cont.TargetPC) { + TargetSection[0] = (CCodeSection **)&m_JumpSection; + TargetSection[1] = (CCodeSection **)&m_ContinueSection; + JumpInfo[0] = &m_Jump; + JumpInfo[1] = &m_Cont; + } else { + TargetSection[0] = (CCodeSection **)&m_ContinueSection; + TargetSection[1] = (CCodeSection **)&m_JumpSection; + JumpInfo[0] = &m_Cont; + JumpInfo[1] = &m_Jump; + } + + CCodeBlock * BlockInfo = m_BlockInfo; + + for (int count = 0; count < 2; count ++) + { + if (JumpInfo[count]->TargetPC == (DWORD)-1 || *TargetSection[count] != NULL) + { + continue; + } + if (!JumpInfo[count]->DoneDelaySlot) + { + m_Jump.RegSet = m_RegWorkingSet; + + //this is a special delay slot section + BlockInfo->IncSectionCount(); + *TargetSection[count] = new CCodeSection(BlockInfo,CompilePC() + 4,BlockInfo->NoOfSections()); + (*TargetSection[count])->AddParent(this); + (*TargetSection[count])->m_LinkAllowed = false; + (*TargetSection[count])->InheritConstants(); + + if (!(*TargetSection[count])->FillSectionInfo(END_BLOCK)) + { + return false; + } + (*TargetSection[count])->m_Jump.TargetPC = -1; + (*TargetSection[count])->m_Cont.TargetPC = JumpInfo[count]->TargetPC; + (*TargetSection[count])->m_Cont.FallThrough = true; + (*TargetSection[count])->m_Cont.RegSet = (*TargetSection[count])->m_RegWorkingSet; + JumpInfo[count]->TargetPC = CompilePC() + 4; + + //Create the section that joins with that block + (*TargetSection[count])->m_ContinueSection = BlockInfo->ExistingSection((*TargetSection[count])->m_Cont.TargetPC); + if ((*TargetSection[count])->m_ContinueSection == NULL) { + BlockInfo->IncSectionCount(); + (*TargetSection[count])->m_ContinueSection = new CCodeSection(BlockInfo,(*TargetSection[count])->m_Cont.TargetPC,BlockInfo->NoOfSections()); + (*TargetSection[count])->m_ContinueSection->AddParent((*TargetSection[count])); + (*TargetSection[count])->m_ContinueSection->CreateSectionLinkage(); + } else { + (*TargetSection[count])->m_ContinueSection->AddParent((*TargetSection[count])); + } + } else { + *TargetSection[count] = BlockInfo->ExistingSection(JumpInfo[count]->TargetPC); + if (*TargetSection[count] == NULL) { + BlockInfo->IncSectionCount(); + *TargetSection[count] = new CCodeSection(BlockInfo,JumpInfo[count]->TargetPC,BlockInfo->NoOfSections()); + (*TargetSection[count])->AddParent(this); + (*TargetSection[count])->CreateSectionLinkage(); + } else { + (*TargetSection[count])->AddParent(this); + } + } + } + return true; +} + bool CCodeSection::GenerateX86Code ( DWORD Test ) { if (this == NULL) { return false; } @@ -946,9 +1216,7 @@ bool CCodeSection::GenerateX86Code ( DWORD Test ) UnknownOpcode(); break; } - #ifdef tofix - if (!bRegCaching()) { WriteBackRegisters(); } - #endif + if (!bRegCaching()) { m_RegWorkingSet.WriteBackRegisters(); } m_RegWorkingSet.UnMap_AllFPRs(); if ((m_CompilePC &0xFFC) == 0xFFC) @@ -985,3 +1253,1122 @@ bool CCodeSection::GenerateX86Code ( DWORD Test ) } return true; } + +void CCodeSection::AddParent(CCodeSection * Parent ) +{ + if (this == NULL) { return; } + if (Parent == NULL) + { + m_RegEnter.Initilize(); + m_RegWorkingSet = m_RegEnter; + return; + } + + // check to see if we already have the parent in the list + for (SECTION_LIST::iterator iter = m_ParentSection.begin(); iter != m_ParentSection.end(); iter++) + { + if (*iter == Parent) + { + return; + } + } + m_ParentSection.push_back(Parent); + + if (m_ParentSection.size() == 1) + { + if (Parent->m_ContinueSection == this) { + m_RegEnter = Parent->m_Cont.RegSet; + } else if (Parent->m_JumpSection == this) { + m_RegEnter = Parent->m_Jump.RegSet; + } else { + _Notify->DisplayError("How are these sections joined?????"); + } + m_RegWorkingSet = m_RegEnter; + } else { + if (Parent->m_ContinueSection == this) { + TestRegConstantStates(Parent->m_Cont.RegSet,m_RegEnter); + } + if (Parent->m_JumpSection == this) { + TestRegConstantStates(Parent->m_Jump.RegSet,m_RegEnter); + } + m_RegWorkingSet = m_RegEnter; + } +} + +void CCodeSection::TestRegConstantStates( CRegInfo & Base, CRegInfo & Reg ) +{ + for (int count = 0; count < 32; count++) { + if (Reg.MipsRegState(count) != Base.MipsRegState(count)) { + Reg.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; + } + if (Reg.IsConst(count)) + { + if (Reg.Is32Bit(count)) + { + if (Reg.MipsRegLo(count) != Base.MipsRegLo(count)) { + Reg.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; + } + } else { + if (Reg.MipsReg(count) != Base.MipsReg(count)) { + Reg.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; + } + } + + } + } +} + +void CCodeSection::DetermineLoop(DWORD Test, DWORD Test2, DWORD TestID) +{ + if (this == NULL) { return; } + + if (m_SectionID == TestID) + { + if (m_Test2 != Test2) + { + m_Test2 = Test2; + m_ContinueSection->DetermineLoop(Test,Test2,TestID); + m_JumpSection->DetermineLoop(Test,Test2,TestID); + + if (m_Test != Test) + { + m_Test = Test; + if (m_ContinueSection != NULL) + { + m_ContinueSection->DetermineLoop(Test,m_BlockInfo->NextTest(),m_ContinueSection->m_SectionID); + } + if (m_JumpSection != NULL) + { + m_JumpSection->DetermineLoop(Test,m_BlockInfo->NextTest(),m_JumpSection->m_SectionID); + } + } + } else { + m_InLoop = true; + } + } else { + if (m_Test2 != Test2) + { + m_Test2 = Test2; + m_ContinueSection->DetermineLoop(Test,Test2,TestID); + m_JumpSection->DetermineLoop(Test,Test2,TestID); + } + } +} + +bool CCodeSection::FixConstants (DWORD Test) +{ + if (this == NULL) { return false; } + if (m_Test == Test) { return false; } + m_Test = Test; + + InheritConstants(); + + bool Changed = false; + CRegInfo Original[2] = { m_Cont.RegSet, m_Jump.RegSet }; + + if (!m_ParentSection.empty()) + { + for (SECTION_LIST::iterator iter = m_ParentSection.begin(); iter != m_ParentSection.end(); iter++) + { + CCodeSection * Parent = *iter; + if (Parent->m_ContinueSection == this) + { + for (int count = 0; count < 32; count++) + { + if (m_RegEnter.MipsRegState(count) != Parent->m_Cont.RegSet.MipsRegState(count)) { + m_RegEnter.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; + //*Changed = true; + } + m_RegEnter.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; + } + } + if (Parent->m_JumpSection == this) { + for (int count = 0; count < 32; count++) { + if (m_RegEnter.MipsRegState(count) != Parent->m_Jump.RegSet.MipsRegState(count)) { + m_RegEnter.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; + //*Changed = true; + } + } + } + m_RegWorkingSet = m_RegEnter; + } + } + + FillSectionInfo(NORMAL); + if (Original[0] != m_Cont.RegSet) + { + Changed = true; + } + if (Original[1] != m_Jump.RegSet) + { + Changed = true; + } + + if (m_JumpSection && m_JumpSection->FixConstants(Test)) { Changed = true; } + if (m_ContinueSection && m_ContinueSection->FixConstants(Test)) { Changed = true; } + + return Changed; +} + +CCodeSection * CCodeSection::ExistingSection(DWORD Addr, DWORD Test) +{ + if (this == NULL) { return NULL; } + if (m_EnterPC == Addr && m_LinkAllowed) + { + return this; + } + if (m_Test == Test) { return NULL; } + m_Test = Test; + + CCodeSection * Section = m_JumpSection->ExistingSection(Addr,Test); + if (Section != NULL) { return Section; } + Section = m_ContinueSection->ExistingSection(Addr,Test); + if (Section != NULL) { return Section; } + + return NULL; +} + +void CCodeSection::InheritConstants( void ) +{ + if (m_ParentSection.empty()) + { + m_RegEnter.Initilize(); + m_RegWorkingSet = m_RegEnter; + return; + } + + CCodeSection * Parent = *(m_ParentSection.begin()); + CRegInfo * RegSet = (this == Parent->m_ContinueSection?&Parent->m_Cont.RegSet:&Parent->m_Jump.RegSet); + m_RegEnter = *RegSet; + m_RegWorkingSet = *RegSet; + + for (SECTION_LIST::iterator iter = m_ParentSection.begin(); iter != m_ParentSection.end(); iter++) + { + if (iter == m_ParentSection.begin()) { continue; } + Parent = *iter; + RegSet = this == Parent->m_ContinueSection?&Parent->m_Cont.RegSet:&Parent->m_Jump.RegSet; + + for (int count = 0; count < 32; count++) { + if (IsConst(count)) { + if (cMipsRegState(count) != RegSet->MipsRegState(count)) { + MipsRegState(count) = CRegInfo::STATE_UNKNOWN; + } else if (Is32Bit(count) && cMipsRegLo(count) != RegSet->cMipsRegLo(count)) { + MipsRegState(count) = CRegInfo::STATE_UNKNOWN; + } else if (Is64Bit(count) && cMipsReg(count) != RegSet->cMipsReg(count)) { + MipsRegState(count) = CRegInfo::STATE_UNKNOWN; + } + } + } + } + m_RegEnter = m_RegWorkingSet; +} + +bool CCodeSection::FillSectionInfo(STEP_TYPE StartStepType) +{ + OPCODE Command; + + if (m_CompiledLocation != NULL) { return true; } + m_CompilePC = m_EnterPC; + m_RegWorkingSet = m_RegEnter; + m_NextInstruction = StartStepType; + do { + if (!_MMU->LW_VAddr(CompilePC(), Command.Hex)) { + DisplayError(GS(MSG_FAIL_LOAD_WORD)); + return false; + } + switch (Command.op) { + case R4300i_SPECIAL: + switch (Command.funct) { + case R4300i_SPECIAL_SLL: + if (Command.rd == 0) { break; } + if (m_InLoop && Command.rt == Command.rd) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rd) = MipsRegLo(Command.rt) << Command.sa; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_SRL: + if (Command.rd == 0) { break; } + if (m_InLoop && Command.rt == Command.rd) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rd) = MipsRegLo(Command.rt) >> Command.sa; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_SRA: + if (Command.rd == 0) { break; } + if (m_InLoop && Command.rt == Command.rd) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rd) = MipsRegLo_S(Command.rt) >> Command.sa; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_SLLV: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rd) = MipsRegLo(Command.rt) << (MipsRegLo(Command.rs) & 0x1F); + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_SRLV: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rd) = MipsRegLo(Command.rt) >> (MipsRegLo(Command.rs) & 0x1F); + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_SRAV: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rd) = MipsRegLo_S(Command.rt) >> (MipsRegLo(Command.rs) & 0x1F); + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_JR: + if (IsConst(Command.rs)) { + m_Jump.TargetPC = MipsRegLo(Command.rs); + } else { + m_Jump.TargetPC = (DWORD)-1; + } + m_NextInstruction = DELAY_SLOT; + break; + case R4300i_SPECIAL_JALR: + MipsRegLo(Command.rd) = CompilePC() + 8; + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + if (IsConst(Command.rs)) { + m_Jump.TargetPC = MipsRegLo(Command.rs); + } else { + m_Jump.TargetPC = (DWORD)-1; + } + m_NextInstruction = DELAY_SLOT; + break; + case R4300i_SPECIAL_SYSCALL: + case R4300i_SPECIAL_BREAK: + m_NextInstruction = END_BLOCK; + m_CompilePC -= 4; + break; + case R4300i_SPECIAL_MFHI: MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; break; + case R4300i_SPECIAL_MTHI: break; + case R4300i_SPECIAL_MFLO: MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; break; + case R4300i_SPECIAL_MTLO: break; + case R4300i_SPECIAL_DSLLV: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + MipsReg(Command.rd) = Is64Bit(Command.rt)?cMipsReg(Command.rt):(QWORD)MipsRegLo_S(Command.rt) << (MipsRegLo(Command.rs) & 0x3F); + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DSRLV: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + MipsReg(Command.rd) = Is64Bit(Command.rt)?cMipsReg(Command.rt):(QWORD)MipsRegLo_S(Command.rt) >> (MipsRegLo(Command.rs) & 0x3F); + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DSRAV: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + MipsReg(Command.rd) = Is64Bit(Command.rt)?cMipsReg_S(Command.rt):(_int64)MipsRegLo_S(Command.rt) >> (MipsRegLo(Command.rs) & 0x3F); + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_MULT: break; + case R4300i_SPECIAL_MULTU: break; + case R4300i_SPECIAL_DIV: break; + case R4300i_SPECIAL_DIVU: break; + case R4300i_SPECIAL_DMULT: break; + case R4300i_SPECIAL_DMULTU: break; + case R4300i_SPECIAL_DDIV: break; + case R4300i_SPECIAL_DDIVU: break; + case R4300i_SPECIAL_ADD: + case R4300i_SPECIAL_ADDU: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsRegLo(Command.rd) = MipsRegLo(Command.rs) + MipsRegLo(Command.rt); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_SUB: + case R4300i_SPECIAL_SUBU: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsRegLo(Command.rd) = MipsRegLo(Command.rs) - MipsRegLo(Command.rt); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_AND: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + if (Is64Bit(Command.rt) && Is64Bit(Command.rs)) { + MipsReg(Command.rd) = cMipsReg(Command.rt) & cMipsReg(Command.rs); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + } else if (Is64Bit(Command.rt) || Is64Bit(Command.rs)) { + if (Is64Bit(Command.rt)) { + MipsReg(Command.rd) = cMipsReg(Command.rt) & MipsRegLo(Command.rs); + } else { + MipsReg(Command.rd) = MipsRegLo(Command.rt) & cMipsReg(Command.rs); + } + MipsRegState(Command.rd) = CRegInfo::ConstantsType(cMipsReg(Command.rd)); + } else { + MipsRegLo(Command.rd) = MipsRegLo(Command.rt) & MipsRegLo(Command.rs); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + } + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_OR: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + if (Is64Bit(Command.rt) && Is64Bit(Command.rs)) { + MipsReg(Command.rd) = cMipsReg(Command.rt) | cMipsReg(Command.rs); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + } else if (Is64Bit(Command.rt) || Is64Bit(Command.rs)) { + if (Is64Bit(Command.rt)) { + MipsReg(Command.rd) = cMipsReg(Command.rt) | MipsRegLo(Command.rs); + } else { + MipsReg(Command.rd) = MipsRegLo(Command.rt) | cMipsReg(Command.rs); + } + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + } else { + MipsRegLo(Command.rd) = MipsRegLo(Command.rt) | MipsRegLo(Command.rs); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + } + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_XOR: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + if (Is64Bit(Command.rt) && Is64Bit(Command.rs)) { + MipsReg(Command.rd) = cMipsReg(Command.rt) ^ cMipsReg(Command.rs); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + } else if (Is64Bit(Command.rt) || Is64Bit(Command.rs)) { + if (Is64Bit(Command.rt)) { + MipsReg(Command.rd) = cMipsReg(Command.rt) ^ MipsRegLo(Command.rs); + } else { + MipsReg(Command.rd) = MipsRegLo(Command.rt) ^ cMipsReg(Command.rs); + } + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + } else { + MipsRegLo(Command.rd) = MipsRegLo(Command.rt) ^ MipsRegLo(Command.rs); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + } + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_NOR: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + if (Is64Bit(Command.rt) && Is64Bit(Command.rs)) { + MipsReg(Command.rd) = ~(cMipsReg(Command.rt) | cMipsReg(Command.rs)); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + } else if (Is64Bit(Command.rt) || Is64Bit(Command.rs)) { + if (Is64Bit(Command.rt)) { + MipsReg(Command.rd) = ~(cMipsReg(Command.rt) | MipsRegLo(Command.rs)); + } else { + MipsReg(Command.rd) = ~(MipsRegLo(Command.rt) | cMipsReg(Command.rs)); + } + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + } else { + MipsRegLo(Command.rd) = ~(MipsRegLo(Command.rt) | MipsRegLo(Command.rs)); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + } + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_SLT: + if (Command.rd == 0) { break; } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + if (Is64Bit(Command.rt) || Is64Bit(Command.rs)) { + if (Is64Bit(Command.rt)) { + MipsRegLo(Command.rd) = (MipsRegLo_S(Command.rs) < cMipsReg_S(Command.rt))?1:0; + } else { + MipsRegLo(Command.rd) = (cMipsReg_S(Command.rs) < MipsRegLo_S(Command.rt))?1:0; + } + } else { + MipsRegLo(Command.rd) = (MipsRegLo_S(Command.rs) < MipsRegLo_S(Command.rt))?1:0; + } + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_SLTU: + if (Command.rd == 0) { break; } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + if (Is64Bit(Command.rt) || Is64Bit(Command.rs)) { + if (Is64Bit(Command.rt)) { + MipsRegLo(Command.rd) = (MipsRegLo(Command.rs) < cMipsReg(Command.rt))?1:0; + } else { + MipsRegLo(Command.rd) = (cMipsReg(Command.rs) < MipsRegLo(Command.rt))?1:0; + } + } else { + MipsRegLo(Command.rd) = (MipsRegLo(Command.rs) < MipsRegLo(Command.rt))?1:0; + } + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DADD: + case R4300i_SPECIAL_DADDU: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsReg(Command.rd) = + Is64Bit(Command.rs)?cMipsReg(Command.rs):(_int64)MipsRegLo_S(Command.rs) + + Is64Bit(Command.rt)?cMipsReg(Command.rt):(_int64)MipsRegLo_S(Command.rt); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DSUB: + case R4300i_SPECIAL_DSUBU: + if (Command.rd == 0) { break; } + if (m_InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt) && IsConst(Command.rs)) { + MipsReg(Command.rd) = + Is64Bit(Command.rs)?cMipsReg(Command.rs):(_int64)MipsRegLo_S(Command.rs) - + Is64Bit(Command.rt)?cMipsReg(Command.rt):(_int64)MipsRegLo_S(Command.rt); + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DSLL: + if (Command.rd == 0) { break; } + if (m_InLoop && Command.rt == Command.rd) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + MipsReg(Command.rd) = Is64Bit(Command.rt)?cMipsReg(Command.rt):(_int64)MipsRegLo_S(Command.rt) << Command.sa; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DSRL: + if (Command.rd == 0) { break; } + if (m_InLoop && Command.rt == Command.rd) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + MipsReg(Command.rd) = Is64Bit(Command.rt)?cMipsReg(Command.rt):(QWORD)MipsRegLo_S(Command.rt) >> Command.sa; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DSRA: + if (Command.rd == 0) { break; } + if (m_InLoop && Command.rt == Command.rd) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + MipsReg_S(Command.rd) = Is64Bit(Command.rt)?cMipsReg_S(Command.rt):(_int64)MipsRegLo_S(Command.rt) >> Command.sa; + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DSLL32: + if (Command.rd == 0) { break; } + if (m_InLoop && Command.rt == Command.rd) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; + MipsReg(Command.rd) = MipsRegLo(Command.rt) << (Command.sa + 32); + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DSRL32: + if (Command.rd == 0) { break; } + if (m_InLoop && Command.rt == Command.rd) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rd) = (DWORD)(cMipsReg(Command.rt) >> (Command.sa + 32)); + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SPECIAL_DSRA32: + if (Command.rd == 0) { break; } + if (m_InLoop && Command.rt == Command.rd) { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rt)) { + MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rd) = (DWORD)(cMipsReg_S(Command.rt) >> (Command.sa + 32)); + } else { + MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; + } + break; + default: +#ifndef EXTERNAL_RELEASE + if (Command.Hex == 0x00000001) { break; } + DisplayError("Unhandled R4300i OpCode in FillSectionInfo 5\n%s", + R4300iOpcodeName(Command.Hex,CompilePC())); +#endif + m_NextInstruction = END_BLOCK; + m_CompilePC -= 4; + } + break; + case R4300i_REGIMM: + switch (Command.rt) { + case R4300i_REGIMM_BLTZ: + case R4300i_REGIMM_BGEZ: + m_NextInstruction = DELAY_SLOT; + m_Cont.TargetPC = CompilePC() + 8; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + if (!DelaySlotEffectsCompare(CompilePC(),Command.rs,0)) { + m_Jump.PermLoop = true; + } + } + break; + case R4300i_REGIMM_BLTZL: + case R4300i_REGIMM_BGEZL: + m_NextInstruction = LIKELY_DELAY_SLOT; + m_Cont.TargetPC = CompilePC() + 8; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + if (!DelaySlotEffectsCompare(CompilePC(),Command.rs,0)) { + m_Jump.PermLoop = true; + } + } + break; + case R4300i_REGIMM_BLTZAL: + MipsRegLo(31) = CompilePC() + 8; + MipsRegState(31) = CRegInfo::STATE_CONST_32; + m_Cont.TargetPC = CompilePC() + 8; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + if (!DelaySlotEffectsCompare(CompilePC(),Command.rs,0)) { + m_Jump.PermLoop = true; + } + } + break; + case R4300i_REGIMM_BGEZAL: + m_NextInstruction = DELAY_SLOT; + if (IsConst(Command.rs)) + { + __int64 Value; + if (Is32Bit(Command.rs)) + { + Value = MipsRegLo_S(Command.rs); + } else { + Value = cMipsReg_S(Command.rs); + } + if (Value >= 0) { + MipsRegLo(31) = CompilePC() + 8; + MipsRegState(31) = CRegInfo::STATE_CONST_32; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + if (!DelaySlotEffectsCompare(CompilePC(),31,0)) { + m_Jump.PermLoop = true; + } + } + break; + } + } + + + MipsRegLo(31) = CompilePC() + 8; + MipsRegState(31) = CRegInfo::STATE_CONST_32; + m_Cont.TargetPC = CompilePC() + 8; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + if (!DelaySlotEffectsCompare(CompilePC(),Command.rs,0)) { + m_Jump.PermLoop = true; + } + } + break; + default: +#ifndef EXTERNAL_RELEASE + if (Command.Hex == 0x0407000D) { break; } + DisplayError("Unhandled R4300i OpCode in FillSectionInfo 4\n%s", + R4300iOpcodeName(Command.Hex,CompilePC())); +#endif + m_NextInstruction = END_BLOCK; + m_CompilePC -= 4; + } + break; + case R4300i_JAL: + m_NextInstruction = DELAY_SLOT; + MipsRegLo(31) = CompilePC() + 8; + MipsRegState(31) = CRegInfo::STATE_CONST_32; + m_Jump.TargetPC = (CompilePC() & 0xF0000000) + (Command.target << 2); + if (CompilePC() == m_Jump.TargetPC) { + if (!DelaySlotEffectsCompare(CompilePC(),31,0)) { + m_Jump.PermLoop = true; + } + } + break; + case R4300i_J: + m_NextInstruction = DELAY_SLOT; + m_Jump.TargetPC = (CompilePC() & 0xF0000000) + (Command.target << 2); + if (CompilePC() == m_Jump.TargetPC) { m_Jump.PermLoop = true; } + break; + case R4300i_BEQ: + m_NextInstruction = DELAY_SLOT; + m_Cont.TargetPC = CompilePC() + 8; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + if (!DelaySlotEffectsCompare(CompilePC(),Command.rs,Command.rt)) { + m_Jump.PermLoop = true; + } + } + if (IsConst(Command.rs) && IsConst(Command.rt)) + { + __int64 Value1, Value2; + if (Is32Bit(Command.rs)) + { + Value1 = MipsRegLo_S(Command.rs); + } else { + Value1 = cMipsReg_S(Command.rs); + } + if (Is32Bit(Command.rt)) + { + Value2 = MipsRegLo_S(Command.rt); + } else { + Value2 = cMipsReg_S(Command.rt); + } + if (Value1 == Value2) + { + m_Cont.TargetPC = -1; + } + } + break; + case R4300i_BNE: + case R4300i_BLEZ: + case R4300i_BGTZ: + m_NextInstruction = DELAY_SLOT; + m_Cont.TargetPC = CompilePC() + 8; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + if (!DelaySlotEffectsCompare(CompilePC(),Command.rs,Command.rt)) { + m_Jump.PermLoop = true; + } + } + break; + case R4300i_ADDI: + case R4300i_ADDIU: + if (Command.rt == 0) { break; } + if (m_InLoop && Command.rs == Command.rt) { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rs)) { + MipsRegLo(Command.rt) = MipsRegLo(Command.rs) + (short)Command.immediate; + MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; + } else { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SLTI: + if (Command.rt == 0) { break; } + if (IsConst(Command.rs)) { + if (Is64Bit(Command.rs)) { + MipsRegLo(Command.rt) = (cMipsReg_S(Command.rs) < (_int64)((short)Command.immediate))?1:0; + } else { + MipsRegLo(Command.rt) = (MipsRegLo_S(Command.rs) < (int)((short)Command.immediate))?1:0; + } + MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; + } else { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_SLTIU: + if (Command.rt == 0) { break; } + if (IsConst(Command.rs)) { + if (Is64Bit(Command.rs)) { + MipsRegLo(Command.rt) = (cMipsReg(Command.rs) < (unsigned _int64)((short)Command.immediate))?1:0; + } else { + MipsRegLo(Command.rt) = (MipsRegLo(Command.rs) < (DWORD)((short)Command.immediate))?1:0; + } + MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; + } else { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_LUI: + if (Command.rt == 0) { break; } + MipsRegLo(Command.rt) = ((short)Command.offset << 16); + MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; + break; + case R4300i_ANDI: + if (Command.rt == 0) { break; } + if (m_InLoop && Command.rs == Command.rt) { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rs)) { + MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rt) = MipsRegLo(Command.rs) & Command.immediate; + } else { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_ORI: + if (Command.rt == 0) { break; } + if (m_InLoop && Command.rs == Command.rt) { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rs)) { + MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rt) = MipsRegLo(Command.rs) | Command.immediate; + } else { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_XORI: + if (Command.rt == 0) { break; } + if (m_InLoop && Command.rs == Command.rt) { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rs)) { + MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; + MipsRegLo(Command.rt) = MipsRegLo(Command.rs) ^ Command.immediate; + } else { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_CP0: + switch (Command.rs) { + case R4300i_COP0_MF: + if (Command.rt == 0) { break; } + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + break; + case R4300i_COP0_MT: break; + default: + if ( (Command.rs & 0x10 ) != 0 ) { + switch( Command.funct ) { + case R4300i_COP0_CO_TLBR: break; + case R4300i_COP0_CO_TLBWI: break; + case R4300i_COP0_CO_TLBWR: break; + case R4300i_COP0_CO_TLBP: break; + case R4300i_COP0_CO_ERET: m_NextInstruction = END_BLOCK; break; + default: +#ifndef EXTERNAL_RELEASE + DisplayError("Unhandled R4300i OpCode in FillSectionInfo\n%s", + R4300iOpcodeName(Command.Hex,CompilePC())); +#endif + m_NextInstruction = END_BLOCK; + m_CompilePC -= 4; + } + } else { +#ifndef EXTERNAL_RELEASE + DisplayError("Unhandled R4300i OpCode in FillSectionInfo 3\n%s", + R4300iOpcodeName(Command.Hex,CompilePC())); +#endif + m_NextInstruction = END_BLOCK; + m_CompilePC -= 4; + } + } + break; + case R4300i_CP1: + switch (Command.fmt) { + case R4300i_COP1_CF: + case R4300i_COP1_MF: + case R4300i_COP1_DMF: + if (Command.rt == 0) { break; } + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + break; + case R4300i_COP1_BC: + switch (Command.ft) { + case R4300i_COP1_BC_BCFL: + case R4300i_COP1_BC_BCTL: + m_NextInstruction = LIKELY_DELAY_SLOT; + m_Cont.TargetPC = CompilePC() + 8; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + int EffectDelaySlot; + OPCODE NewCommand; + + if (!_MMU->LW_VAddr(CompilePC() + 4, NewCommand.Hex)) { + DisplayError(GS(MSG_FAIL_LOAD_WORD)); + ExitThread(0); + } + + EffectDelaySlot = false; + if (NewCommand.op == R4300i_CP1) { + if (NewCommand.fmt == R4300i_COP1_S && (NewCommand.funct & 0x30) == 0x30 ) { + EffectDelaySlot = true; + } + if (NewCommand.fmt == R4300i_COP1_D && (NewCommand.funct & 0x30) == 0x30 ) { + EffectDelaySlot = true; + } + } + if (!EffectDelaySlot) { + m_Jump.PermLoop = true; + } + } + break; + case R4300i_COP1_BC_BCF: + case R4300i_COP1_BC_BCT: + m_NextInstruction = DELAY_SLOT; + m_Cont.TargetPC = CompilePC() + 8; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + int EffectDelaySlot; + OPCODE NewCommand; + + if (!_MMU->LW_VAddr(CompilePC() + 4, NewCommand.Hex)) { + DisplayError(GS(MSG_FAIL_LOAD_WORD)); + ExitThread(0); + } + + EffectDelaySlot = false; + if (NewCommand.op == R4300i_CP1) { + if (NewCommand.fmt == R4300i_COP1_S && (NewCommand.funct & 0x30) == 0x30 ) { + EffectDelaySlot = true; + } + if (NewCommand.fmt == R4300i_COP1_D && (NewCommand.funct & 0x30) == 0x30 ) { + EffectDelaySlot = true; + } + } + if (!EffectDelaySlot) { + m_Jump.PermLoop = true; + } + } + break; + } + break; + case R4300i_COP1_MT: break; + case R4300i_COP1_DMT: break; + case R4300i_COP1_CT: break; + case R4300i_COP1_S: break; + case R4300i_COP1_D: break; + case R4300i_COP1_W: break; + case R4300i_COP1_L: break; + default: +#ifndef EXTERNAL_RELEASE + DisplayError("Unhandled R4300i OpCode in FillSectionInfo 2\n%s", + R4300iOpcodeName(Command.Hex,CompilePC())); +#endif + m_NextInstruction = END_BLOCK; + m_CompilePC -= 4; + } + break; + case R4300i_BEQL: + case R4300i_BNEL: + case R4300i_BLEZL: + case R4300i_BGTZL: + m_NextInstruction = LIKELY_DELAY_SLOT; + m_Cont.TargetPC = CompilePC() + 8; + m_Jump.TargetPC = CompilePC() + ((short)Command.offset << 2) + 4; + if (CompilePC() == m_Jump.TargetPC) { + if (!DelaySlotEffectsCompare(CompilePC(),Command.rs,Command.rt)) { + m_Jump.PermLoop = true; + } + } + break; + case R4300i_DADDI: + case R4300i_DADDIU: + if (Command.rt == 0) { break; } + if (m_InLoop && Command.rs == Command.rt) { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + if (IsConst(Command.rs)) { + if (Is64Bit(Command.rs)) { + int imm32 = (short)Command.immediate; + __int64 imm64 = imm32; + MipsReg_S(Command.rt) = MipsRegLo_S(Command.rs) + imm64; + } else { + MipsReg_S(Command.rt) = MipsRegLo_S(Command.rs) + (short)Command.immediate; + } + MipsRegState(Command.rt) = CRegInfo::STATE_CONST_64; + } else { + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + } + break; + case R4300i_LDR: + case R4300i_LDL: + case R4300i_LB: + case R4300i_LH: + case R4300i_LWL: + case R4300i_LW: + case R4300i_LWU: + case R4300i_LL: + case R4300i_LBU: + case R4300i_LHU: + case R4300i_LWR: + case R4300i_SC: + if (Command.rt == 0) { break; } + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + break; + case R4300i_SB: break; + case R4300i_SH: break; + case R4300i_SWL: break; + case R4300i_SW: break; + case R4300i_SWR: break; + case R4300i_SDL: break; + case R4300i_SDR: break; + case R4300i_CACHE: break; + case R4300i_LWC1: break; + case R4300i_SWC1: break; + case R4300i_LDC1: break; + case R4300i_LD: + if (Command.rt == 0) { break; } + MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; + break; + case R4300i_SDC1: break; + case R4300i_SD: break; + default: + m_NextInstruction = END_BLOCK; + m_CompilePC -= 4; + if (Command.Hex == 0x7C1C97C0) { break; } + if (Command.Hex == 0x7FFFFFFF) { break; } + if (Command.Hex == 0xF1F3F5F7) { break; } + if (Command.Hex == 0xC1200000) { break; } + if (Command.Hex == 0x4C5A5353) { break; } +#ifndef EXTERNAL_RELEASE + DisplayError("Unhandled R4300i OpCode in FillSectionInfo 1\n%s\n%X", + R4300iOpcodeName(Command.Hex,CompilePC()),Command.Hex); +#endif + } + +// if (CompilePC() == 0x8005E4B8) { +//CPU_Message("%X: %s %s = %d",CompilePC(),R4300iOpcodeName(Command.Hex,CompilePC()), +// CRegName::GPR[8],cMipsRegState(8)); +//_asm int 3 +// } + switch (m_NextInstruction) { + case NORMAL: + m_CompilePC += 4; + break; + case DELAY_SLOT: + m_NextInstruction = DELAY_SLOT_DONE; + m_CompilePC += 4; + break; + case LIKELY_DELAY_SLOT: + if (m_Cont.TargetPC == m_Jump.TargetPC) + { + m_Jump.RegSet = m_RegWorkingSet; + m_Cont.DoneDelaySlot = false; + m_Cont.RegSet = m_RegWorkingSet; + m_Cont.DoneDelaySlot = true; + m_NextInstruction = END_BLOCK; + } else { + m_Cont.RegSet = m_RegWorkingSet; + m_Cont.DoneDelaySlot = true; + m_NextInstruction = LIKELY_DELAY_SLOT_DONE; + m_CompilePC += 4; + } + break; + case DELAY_SLOT_DONE: + m_Cont.RegSet = m_RegWorkingSet; + m_Jump.RegSet = m_RegWorkingSet; + m_Cont.DoneDelaySlot = true; + m_Jump.DoneDelaySlot = true; + m_NextInstruction = END_BLOCK; + break; + case LIKELY_DELAY_SLOT_DONE: + m_Jump.RegSet = m_RegWorkingSet; + m_Jump.DoneDelaySlot = true; + m_NextInstruction = END_BLOCK; + break; + } + if ((CompilePC() & 0xFFFFF000) != (m_EnterPC & 0xFFFFF000)) { + if (m_NextInstruction != END_BLOCK && m_NextInstruction != NORMAL) { + // DisplayError("Branch running over delay slot ???\nm_NextInstruction == %d",m_NextInstruction); + m_Cont.TargetPC = (DWORD)-1; + m_Jump.TargetPC = (DWORD)-1; + } + m_NextInstruction = END_BLOCK; + m_CompilePC -= 4; + } + } while (m_NextInstruction != END_BLOCK); + + if (m_Cont.TargetPC != (DWORD)-1) { + if ((m_Cont.TargetPC & 0xFFFFF000) != (m_EnterPC & 0xFFFFF000)) { + m_Cont.TargetPC = (DWORD)-1; + } + } + if (m_Jump.TargetPC != (DWORD)-1) { + if (m_Jump.TargetPC < m_BlockInfo->VAddrEnter()) + { + m_Jump.TargetPC = (DWORD)-1; + } + if ((m_Jump.TargetPC & 0xFFFFF000) != (m_EnterPC & 0xFFFFF000)) { + m_Jump.TargetPC = (DWORD)-1; + } + } + return true; +} + diff --git a/Source/Project64/N64 System/Recompiler/Code Section.h b/Source/Project64/N64 System/Recompiler/Code Section.h index 22598f436..e94379f43 100644 --- a/Source/Project64/N64 System/Recompiler/Code Section.h +++ b/Source/Project64/N64 System/Recompiler/Code Section.h @@ -5,17 +5,24 @@ class CCodeBlock; class CCodeSection : private CRecompilerOps { + typedef std::list SECTION_LIST; + public: CCodeSection( CCodeBlock * CodeBlock, DWORD EnterPC, DWORD ID); ~CCodeSection( void ); - void CompileCop1Test ( void ); - bool GenerateX86Code ( DWORD Test ); - void GenerateSectionLinkage ( void ); - void CompileSystemCheck ( DWORD TargetPC, const CRegInfo &RegSet ); - void CompileExit ( DWORD JumpPC, DWORD TargetPC, CRegInfo ExitRegSet, CExitInfo::EXIT_REASON reason, int CompileNow, void (*x86Jmp)(const char * Label, DWORD Value)); + void CompileCop1Test ( void ); + bool CreateSectionLinkage ( void ); + bool GenerateX86Code ( DWORD Test ); + void GenerateSectionLinkage ( void ); + void CompileSystemCheck ( DWORD TargetPC, const CRegInfo &RegSet ); + void CompileExit ( DWORD JumpPC, DWORD TargetPC, CRegInfo ExitRegSet, CExitInfo::EXIT_REASON reason, int CompileNow, void (*x86Jmp)(const char * Label, DWORD Value)); + void DetermineLoop ( DWORD Test, DWORD Test2, DWORD TestID ); + bool FixConstants ( DWORD Test ); + CCodeSection * ExistingSection ( DWORD Addr, DWORD Test ); /* Block Connection info */ + SECTION_LIST m_ParentSection; CCodeBlock * const m_BlockInfo; const DWORD m_EnterPC; const DWORD m_SectionID; @@ -23,12 +30,12 @@ public: CCodeSection * m_JumpSection; bool m_LinkAllowed; // are other sections allowed to find block to link to it DWORD m_Test; + DWORD m_Test2; BYTE * m_CompiledLocation; bool m_DelaySlotSection; + bool m_InLoop; - /* SECTION_LIST ParentSection; - DWORD Test2; - bool InLoop; + /* /* Register Info */ @@ -40,6 +47,10 @@ public: private: - + void AddParent ( CCodeSection * Parent ); + void InheritConstants ( void ); + bool FillSectionInfo ( STEP_TYPE StartStepType ); + void TestRegConstantStates ( CRegInfo & Base, CRegInfo & Reg ); + void SyncRegState ( const CRegInfo & SyncTo ); }; diff --git a/Source/Project64/N64 System/Recompiler/Recompiler Class.cpp b/Source/Project64/N64 System/Recompiler/Recompiler Class.cpp index 9465bbec6..e373f159f 100644 --- a/Source/Project64/N64 System/Recompiler/Recompiler Class.cpp +++ b/Source/Project64/N64 System/Recompiler/Recompiler Class.cpp @@ -5,6 +5,7 @@ CRecompiler::CRecompiler(CProfiling & Profile, bool & EndEmulation ) : PROGRAM_COUNTER(_Reg->m_PROGRAM_COUNTER), m_EndEmulation(EndEmulation) { + ResetMemoryStackPos(); } CRecompiler::~CRecompiler() @@ -32,7 +33,6 @@ void CRecompiler::Run() } m_EndEmulation = false; - WriteTrace(TraceError,"CRecompiler::Run Fix g_MemoryStack"); #ifdef tofix *g_MemoryStack = (DWORD)(RDRAM+(_GPR[29].W[0] & 0x1FFFFFFF)); #endif @@ -615,1130 +615,6 @@ BYTE * CRecompiler::CompileDelaySlot(DWORD PC) } } -bool CRecompiler::AnalyseBlock ( CCodeBlock & BlockInfo) -{ - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - if (bLinkBlocks()) - { - CCodeSection * Section = &BlockInfo.ParentSection; - if (!CreateSectionLinkage (Section)) { return false; } - DetermineLoop(Section,CCodeSection::GetNewTestValue(),CCodeSection::GetNewTestValue(), Section->m_SectionID); - while (FixConstants(Section,CCodeSection::GetNewTestValue())) {} - } -#endif - return true; -} - -bool CRecompiler::FixConstants (CCodeSection * Section, DWORD Test) -{ - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - if (Section == NULL) { return false; } - if (Section->Test == Test) { return false; } - Section->Test = Test; - - InheritConstants(Section); - - bool Changed = false; -/* BLOCK_SECTION * Parent; - int count, NoOfParents; - REG_INFO Original[2]; -*/ - CRegInfo Original[2] = { Section->m_Cont.RegSet, Section->m_Jump.RegSet }; - - if (!Section->ParentSection.empty()) { - for (SECTION_LIST::iterator iter = Section->ParentSection.begin(); iter != Section->ParentSection.end(); iter++) - { - CCodeSection * Parent = *iter; - if (Parent->m_ContinueSection == Section) { - for (int count = 0; count < 32; count++) { - if (Section->RegStart.MipsRegState(count) != Parent->m_Cont.RegSet.MipsRegState(count)) { - Section->RegStart.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; - //*Changed = true; - } - Section->RegStart.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; - } - } - if (Parent->m_JumpSection == Section) { - for (int count = 0; count < 32; count++) { - if (Section->RegStart.MipsRegState(count) != Parent->m_Jump.RegSet.MipsRegState(count)) { - Section->RegStart.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; - //*Changed = true; - } - } - } - Section->RegWorking = Section->RegStart; - } - } - - FillSectionInfo(Section, NORMAL); - if (Original[0] != Section->m_Cont.RegSet) - { - Changed = true; - } - if (Original[1] != Section->m_Jump.RegSet) - { - Changed = true; - } - - if (Section->m_JumpSection && FixConstants(Section->m_JumpSection,Test)) { Changed = true; } - if (Section->m_ContinueSection && FixConstants(Section->m_ContinueSection,Test)) { Changed = true; } - - return Changed; -#endif - return false; -} - -void CRecompiler::InheritConstants(CCodeSection * Section) -{ -_Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - if (Section->ParentSection.empty()) - { - Section->RegStart.Initilize(); - Section->RegWorking = Section->RegStart; - return; - } - - CCodeSection * Parent = *(Section->ParentSection.begin()); - CRegInfo * RegSet = (Section == Parent->m_ContinueSection?&Parent->m_Cont.RegSet:&Parent->m_Jump.RegSet); - Section->RegStart = *RegSet; - Section->RegWorking = *RegSet; - - for (SECTION_LIST::iterator iter = Section->ParentSection.begin(); iter != Section->ParentSection.end(); iter++) - { - if (iter == Section->ParentSection.begin()) { continue; } - Parent = *iter; - RegSet = Section == Parent->m_ContinueSection?&Parent->m_Cont.RegSet:&Parent->m_Jump.RegSet; - - for (int count = 0; count < 32; count++) { - if (Section->IsConst(count)) { - if (Section->MipsRegState(count) != RegSet->MipsRegState(count)) { - Section->MipsRegState(count) = CRegInfo::STATE_UNKNOWN; - } else if (Section->Is32Bit(count) && Section->MipsRegLo(count) != RegSet->MipsRegLo(count)) { - Section->MipsRegState(count) = CRegInfo::STATE_UNKNOWN; - } else if (Section->Is64Bit(count) && Section->MipsReg(count) != RegSet->MipsReg(count)) { - Section->MipsRegState(count) = CRegInfo::STATE_UNKNOWN; - } - } - } - } - Section->RegStart = Section->RegWorking; -#endif -} - -CCodeSection * CRecompiler::ExistingSection(CCodeSection * StartSection, DWORD Addr, DWORD Test) -{ -_Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - if (StartSection == NULL) { return NULL; } - if (StartSection->StartPC == Addr && StartSection->LinkAllowed) - { - return StartSection; - } - if (StartSection->Test == Test) { return NULL; } - StartSection->Test = Test; - - CCodeSection * Section = ExistingSection(StartSection->m_JumpSection,Addr,Test); - if (Section != NULL) { return Section; } - Section = ExistingSection(StartSection->m_ContinueSection,Addr,Test); - if (Section != NULL) { return Section; } -#endif - return NULL; -} - -bool CRecompiler::CreateSectionLinkage (CCodeSection * Section) { - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - InheritConstants(Section); - - if (!FillSectionInfo(Section,NORMAL)) - { - return false; - } - - CCodeSection ** TargetSection[2]; - CJumpInfo * JumpInfo[2]; - if (Section->m_Jump.TargetPC < Section->m_Cont.TargetPC) { - TargetSection[0] = (CCodeSection **)&Section->m_JumpSection; - TargetSection[1] = (CCodeSection **)&Section->m_ContinueSection; - JumpInfo[0] = &Section->m_Jump; - JumpInfo[1] = &Section->m_Cont; - } else { - TargetSection[0] = (CCodeSection **)&Section->m_ContinueSection; - TargetSection[1] = (CCodeSection **)&Section->m_JumpSection; - JumpInfo[0] = &Section->m_Cont; - JumpInfo[1] = &Section->m_Jump; - } - - CCodeBlock * BlockInfo = Section->BlockInfo; - - for (int count = 0; count < 2; count ++) - { - if (JumpInfo[count]->TargetPC == (DWORD)-1 || *TargetSection[count] != NULL) - { - continue; - } - if (!JumpInfo[count]->DoneDelaySlot) - { - Section->m_Jump.RegSet = Section->RegWorking; - - //this is a special delay slot section - BlockInfo->NoOfSections += 1; - *TargetSection[count] = new CCodeSection(BlockInfo,CRecompilerOps::CompilePC() + 4,BlockInfo->NoOfSections); - (*TargetSection[count])->AddParent(Section); - (*TargetSection[count])->LinkAllowed = false; - InheritConstants((*TargetSection[count])); - - if (!FillSectionInfo((*TargetSection[count]),END_BLOCK)) - { - return false; - } - (*TargetSection[count])->m_Jump.TargetPC = -1; - (*TargetSection[count])->m_Cont.TargetPC = JumpInfo[count]->TargetPC; - (*TargetSection[count])->m_Cont.FallThrough = true; - (*TargetSection[count])->m_Cont.RegSet = (*TargetSection[count])->RegWorking; - JumpInfo[count]->TargetPC = CRecompilerOps::CompilePC() + 4; - - //Create the section that joins with that block - (*TargetSection[count])->m_ContinueSection = ExistingSection(&BlockInfo->ParentSection,(*TargetSection[count])->m_Cont.TargetPC,CCodeSection::GetNewTestValue()); - if ((*TargetSection[count])->m_ContinueSection == NULL) { - BlockInfo->NoOfSections += 1; - (*TargetSection[count])->m_ContinueSection = new CCodeSection(BlockInfo,(*TargetSection[count])->m_Cont.TargetPC,BlockInfo->NoOfSections); - (*TargetSection[count])->m_ContinueSection->AddParent((*TargetSection[count])); - CreateSectionLinkage((*TargetSection[count])->m_ContinueSection); - } else { - (*TargetSection[count])->m_ContinueSection->AddParent((*TargetSection[count])); - } - } else { - *TargetSection[count] = ExistingSection(&BlockInfo->ParentSection,JumpInfo[count]->TargetPC,CCodeSection::GetNewTestValue()); - if (*TargetSection[count] == NULL) { - BlockInfo->NoOfSections += 1; - *TargetSection[count] = new CCodeSection(BlockInfo,JumpInfo[count]->TargetPC,BlockInfo->NoOfSections); - (*TargetSection[count])->AddParent(Section); - CreateSectionLinkage(*TargetSection[count]); - } else { - (*TargetSection[count])->AddParent(Section); - } - } - } -#endif - return true; -} - -bool CRecompiler::FillSectionInfo(CCodeSection * Section, STEP_TYPE StartStepType) -{ - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - OPCODE Command; - - if (Section->CompiledLocation != NULL) { return true; } - CRecompilerOps::CompilePC() = Section->StartPC; - Section->RegWorking = Section->RegStart; - NextInstruction = StartStepType; - do { - if (!_MMU->LW_VAddr(CRecompilerOps::CompilePC(), Command.Hex)) { - DisplayError(GS(MSG_FAIL_LOAD_WORD)); - return false; - } - switch (Command.op) { - case R4300i_SPECIAL: - switch (Command.funct) { - case R4300i_SPECIAL_SLL: - if (Command.rd == 0) { break; } - if (Section->InLoop && Command.rt == Command.rd) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rd) = Section->MipsRegLo(Command.rt) << Command.sa; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_SRL: - if (Command.rd == 0) { break; } - if (Section->InLoop && Command.rt == Command.rd) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rd) = Section->MipsRegLo(Command.rt) >> Command.sa; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_SRA: - if (Command.rd == 0) { break; } - if (Section->InLoop && Command.rt == Command.rd) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rd) = Section->MipsRegLo_S(Command.rt) >> Command.sa; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_SLLV: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rd) = Section->MipsRegLo(Command.rt) << (Section->MipsRegLo(Command.rs) & 0x1F); - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_SRLV: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rd) = Section->MipsRegLo(Command.rt) >> (Section->MipsRegLo(Command.rs) & 0x1F); - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_SRAV: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rd) = Section->MipsRegLo_S(Command.rt) >> (Section->MipsRegLo(Command.rs) & 0x1F); - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_JR: - if (Section->IsConst(Command.rs)) { - Section->m_Jump.TargetPC = Section->MipsRegLo(Command.rs); - } else { - Section->m_Jump.TargetPC = (DWORD)-1; - } - NextInstruction = DELAY_SLOT; - break; - case R4300i_SPECIAL_JALR: - Section->MipsRegLo(Opcode.rd) = CRecompilerOps::CompilePC() + 8; - Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; - if (Section->IsConst(Command.rs)) { - Section->m_Jump.TargetPC = Section->MipsRegLo(Command.rs); - } else { - Section->m_Jump.TargetPC = (DWORD)-1; - } - NextInstruction = DELAY_SLOT; - break; - case R4300i_SPECIAL_SYSCALL: - case R4300i_SPECIAL_BREAK: - NextInstruction = END_BLOCK; - CRecompilerOps::CompilePC() -= 4; - break; - case R4300i_SPECIAL_MFHI: Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; break; - case R4300i_SPECIAL_MTHI: break; - case R4300i_SPECIAL_MFLO: Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; break; - case R4300i_SPECIAL_MTLO: break; - case R4300i_SPECIAL_DSLLV: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - Section->MipsReg(Command.rd) = Section->Is64Bit(Command.rt)?Section->MipsReg(Command.rt):(QWORD)Section->MipsRegLo_S(Command.rt) << (Section->MipsRegLo(Command.rs) & 0x3F); - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DSRLV: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - Section->MipsReg(Command.rd) = Section->Is64Bit(Command.rt)?Section->MipsReg(Command.rt):(QWORD)Section->MipsRegLo_S(Command.rt) >> (Section->MipsRegLo(Command.rs) & 0x3F); - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DSRAV: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - Section->MipsReg(Command.rd) = Section->Is64Bit(Command.rt)?Section->MipsReg_S(Command.rt):(_int64)Section->MipsRegLo_S(Command.rt) >> (Section->MipsRegLo(Command.rs) & 0x3F); - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_MULT: break; - case R4300i_SPECIAL_MULTU: break; - case R4300i_SPECIAL_DIV: break; - case R4300i_SPECIAL_DIVU: break; - case R4300i_SPECIAL_DMULT: break; - case R4300i_SPECIAL_DMULTU: break; - case R4300i_SPECIAL_DDIV: break; - case R4300i_SPECIAL_DDIVU: break; - case R4300i_SPECIAL_ADD: - case R4300i_SPECIAL_ADDU: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsRegLo(Command.rd) = Section->MipsRegLo(Command.rs) + Section->MipsRegLo(Command.rt); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_SUB: - case R4300i_SPECIAL_SUBU: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsRegLo(Command.rd) = Section->MipsRegLo(Command.rs) - Section->MipsRegLo(Command.rt); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_AND: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - if (Section->Is64Bit(Command.rt) && Section->Is64Bit(Command.rs)) { - Section->MipsReg(Command.rd) = Section->MipsReg(Command.rt) & Section->MipsReg(Command.rs); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - } else if (Section->Is64Bit(Command.rt) || Section->Is64Bit(Command.rs)) { - if (Section->Is64Bit(Command.rt)) { - Section->MipsReg(Command.rd) = Section->MipsReg(Command.rt) & Section->MipsRegLo(Command.rs); - } else { - Section->MipsReg(Command.rd) = Section->MipsRegLo(Command.rt) & Section->MipsReg(Command.rs); - } - Section->MipsRegState(Command.rd) = CRegInfo::ConstantsType(Section->MipsReg(Command.rd)); - } else { - Section->MipsRegLo(Command.rd) = Section->MipsRegLo(Command.rt) & Section->MipsRegLo(Command.rs); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - } - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_OR: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - if (Section->Is64Bit(Command.rt) && Section->Is64Bit(Command.rs)) { - Section->MipsReg(Command.rd) = Section->MipsReg(Command.rt) | Section->MipsReg(Command.rs); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - } else if (Section->Is64Bit(Command.rt) || Section->Is64Bit(Command.rs)) { - if (Section->Is64Bit(Command.rt)) { - Section->MipsReg(Command.rd) = Section->MipsReg(Command.rt) | Section->MipsRegLo(Command.rs); - } else { - Section->MipsReg(Command.rd) = Section->MipsRegLo(Command.rt) | Section->MipsReg(Command.rs); - } - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - } else { - Section->MipsRegLo(Command.rd) = Section->MipsRegLo(Command.rt) | Section->MipsRegLo(Command.rs); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - } - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_XOR: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - if (Section->Is64Bit(Command.rt) && Section->Is64Bit(Command.rs)) { - Section->MipsReg(Command.rd) = Section->MipsReg(Command.rt) ^ Section->MipsReg(Command.rs); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - } else if (Section->Is64Bit(Command.rt) || Section->Is64Bit(Command.rs)) { - if (Section->Is64Bit(Command.rt)) { - Section->MipsReg(Command.rd) = Section->MipsReg(Command.rt) ^ Section->MipsRegLo(Command.rs); - } else { - Section->MipsReg(Command.rd) = Section->MipsRegLo(Command.rt) ^ Section->MipsReg(Command.rs); - } - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - } else { - Section->MipsRegLo(Command.rd) = Section->MipsRegLo(Command.rt) ^ Section->MipsRegLo(Command.rs); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - } - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_NOR: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - if (Section->Is64Bit(Command.rt) && Section->Is64Bit(Command.rs)) { - Section->MipsReg(Command.rd) = ~(Section->MipsReg(Command.rt) | Section->MipsReg(Command.rs)); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - } else if (Section->Is64Bit(Command.rt) || Section->Is64Bit(Command.rs)) { - if (Section->Is64Bit(Command.rt)) { - Section->MipsReg(Command.rd) = ~(Section->MipsReg(Command.rt) | Section->MipsRegLo(Command.rs)); - } else { - Section->MipsReg(Command.rd) = ~(Section->MipsRegLo(Command.rt) | Section->MipsReg(Command.rs)); - } - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - } else { - Section->MipsRegLo(Command.rd) = ~(Section->MipsRegLo(Command.rt) | Section->MipsRegLo(Command.rs)); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - } - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_SLT: - if (Command.rd == 0) { break; } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - if (Section->Is64Bit(Command.rt) || Section->Is64Bit(Command.rs)) { - if (Section->Is64Bit(Command.rt)) { - Section->MipsRegLo(Command.rd) = (Section->MipsRegLo_S(Command.rs) < Section->MipsReg_S(Command.rt))?1:0; - } else { - Section->MipsRegLo(Command.rd) = (Section->MipsReg_S(Command.rs) < Section->MipsRegLo_S(Command.rt))?1:0; - } - } else { - Section->MipsRegLo(Command.rd) = (Section->MipsRegLo_S(Command.rs) < Section->MipsRegLo_S(Command.rt))?1:0; - } - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_SLTU: - if (Command.rd == 0) { break; } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - if (Section->Is64Bit(Command.rt) || Section->Is64Bit(Command.rs)) { - if (Section->Is64Bit(Command.rt)) { - Section->MipsRegLo(Command.rd) = (Section->MipsRegLo(Command.rs) < Section->MipsReg(Command.rt))?1:0; - } else { - Section->MipsRegLo(Command.rd) = (Section->MipsReg(Command.rs) < Section->MipsRegLo(Command.rt))?1:0; - } - } else { - Section->MipsRegLo(Command.rd) = (Section->MipsRegLo(Command.rs) < Section->MipsRegLo(Command.rt))?1:0; - } - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DADD: - case R4300i_SPECIAL_DADDU: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsReg(Command.rd) = - Section->Is64Bit(Command.rs)?Section->MipsReg(Command.rs):(_int64)Section->MipsRegLo_S(Command.rs) + - Section->Is64Bit(Command.rt)?Section->MipsReg(Command.rt):(_int64)Section->MipsRegLo_S(Command.rt); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DSUB: - case R4300i_SPECIAL_DSUBU: - if (Command.rd == 0) { break; } - if (Section->InLoop && (Command.rt == Command.rd || Command.rs == Command.rd)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt) && Section->IsConst(Command.rs)) { - Section->MipsReg(Command.rd) = - Section->Is64Bit(Command.rs)?Section->MipsReg(Command.rs):(_int64)Section->MipsRegLo_S(Command.rs) - - Section->Is64Bit(Command.rt)?Section->MipsReg(Command.rt):(_int64)Section->MipsRegLo_S(Command.rt); - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DSLL: - if (Command.rd == 0) { break; } - if (Section->InLoop && Command.rt == Command.rd) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - Section->MipsReg(Command.rd) = Section->Is64Bit(Command.rt)?Section->MipsReg(Command.rt):(_int64)Section->MipsRegLo_S(Command.rt) << Command.sa; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DSRL: - if (Command.rd == 0) { break; } - if (Section->InLoop && Command.rt == Command.rd) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - Section->MipsReg(Command.rd) = Section->Is64Bit(Command.rt)?Section->MipsReg(Command.rt):(QWORD)Section->MipsRegLo_S(Command.rt) >> Command.sa; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DSRA: - if (Command.rd == 0) { break; } - if (Section->InLoop && Command.rt == Command.rd) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - Section->MipsReg_S(Command.rd) = Section->Is64Bit(Command.rt)?Section->MipsReg_S(Command.rt):(_int64)Section->MipsRegLo_S(Command.rt) >> Command.sa; - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DSLL32: - if (Command.rd == 0) { break; } - if (Section->InLoop && Command.rt == Command.rd) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_64; - Section->MipsReg(Command.rd) = Section->MipsRegLo(Command.rt) << (Command.sa + 32); - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DSRL32: - if (Command.rd == 0) { break; } - if (Section->InLoop && Command.rt == Command.rd) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rd) = (DWORD)(Section->MipsReg(Command.rt) >> (Command.sa + 32)); - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SPECIAL_DSRA32: - if (Command.rd == 0) { break; } - if (Section->InLoop && Command.rt == Command.rd) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rt)) { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rd) = (DWORD)(Section->MipsReg_S(Command.rt) >> (Command.sa + 32)); - } else { - Section->MipsRegState(Command.rd) = CRegInfo::STATE_UNKNOWN; - } - break; - default: -#ifndef EXTERNAL_RELEASE - if (Command.Hex == 0x00000001) { break; } - DisplayError("Unhandled R4300i OpCode in FillSectionInfo 5\n%s", - R4300iOpcodeName(Command.Hex,CRecompilerOps::CompilePC())); -#endif - NextInstruction = END_BLOCK; - CRecompilerOps::CompilePC() -= 4; - } - break; - case R4300i_REGIMM: - switch (Command.rt) { - case R4300i_REGIMM_BLTZ: - case R4300i_REGIMM_BGEZ: - NextInstruction = DELAY_SLOT; - Section->m_Cont.TargetPC = CRecompilerOps::CompilePC() + 8; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - if (!DelaySlotEffectsCompare(CRecompilerOps::CompilePC(),Command.rs,0)) { - Section->m_Jump.PermLoop = true; - } - } - break; - case R4300i_REGIMM_BLTZL: - case R4300i_REGIMM_BGEZL: - NextInstruction = LIKELY_DELAY_SLOT; - Section->m_Cont.TargetPC = CRecompilerOps::CompilePC() + 8; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - if (!DelaySlotEffectsCompare(CRecompilerOps::CompilePC(),Command.rs,0)) { - Section->m_Jump.PermLoop = true; - } - } - break; - case R4300i_REGIMM_BLTZAL: - Section->MipsRegLo(31) = CRecompilerOps::CompilePC() + 8; - Section->MipsRegState(31) = CRegInfo::STATE_CONST_32; - Section->m_Cont.TargetPC = CRecompilerOps::CompilePC() + 8; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - if (!DelaySlotEffectsCompare(CRecompilerOps::CompilePC(),Command.rs,0)) { - Section->m_Jump.PermLoop = true; - } - } - break; - case R4300i_REGIMM_BGEZAL: - NextInstruction = DELAY_SLOT; - if (Section->IsConst(Command.rs)) - { - __int64 Value; - if (Section->Is32Bit(Command.rs)) - { - Value = Section->MipsRegLo_S(Command.rs); - } else { - Value = Section->MipsReg_S(Command.rs); - } - if (Value >= 0) { - Section->MipsRegLo(31) = CRecompilerOps::CompilePC() + 8; - Section->MipsRegState(31) = CRegInfo::STATE_CONST_32; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - if (!DelaySlotEffectsCompare(CRecompilerOps::CompilePC(),31,0)) { - Section->m_Jump.PermLoop = true; - } - } - break; - } - } - - - Section->MipsRegLo(31) = CRecompilerOps::CompilePC() + 8; - Section->MipsRegState(31) = CRegInfo::STATE_CONST_32; - Section->m_Cont.TargetPC = CRecompilerOps::CompilePC() + 8; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - if (!DelaySlotEffectsCompare(CRecompilerOps::CompilePC(),Command.rs,0)) { - Section->m_Jump.PermLoop = true; - } - } - break; - default: -#ifndef EXTERNAL_RELEASE - if (Command.Hex == 0x0407000D) { break; } - DisplayError("Unhandled R4300i OpCode in FillSectionInfo 4\n%s", - R4300iOpcodeName(Command.Hex,CRecompilerOps::CompilePC())); -#endif - NextInstruction = END_BLOCK; - CRecompilerOps::CompilePC() -= 4; - } - break; - case R4300i_JAL: - NextInstruction = DELAY_SLOT; - Section->MipsRegLo(31) = CRecompilerOps::CompilePC() + 8; - Section->MipsRegState(31) = CRegInfo::STATE_CONST_32; - Section->m_Jump.TargetPC = (CRecompilerOps::CompilePC() & 0xF0000000) + (Command.target << 2); - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - if (!DelaySlotEffectsCompare(CRecompilerOps::CompilePC(),31,0)) { - Section->m_Jump.PermLoop = true; - } - } - break; - case R4300i_J: - NextInstruction = DELAY_SLOT; - Section->m_Jump.TargetPC = (CRecompilerOps::CompilePC() & 0xF0000000) + (Command.target << 2); - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { Section->m_Jump.PermLoop = true; } - break; - case R4300i_BEQ: - NextInstruction = DELAY_SLOT; - Section->m_Cont.TargetPC = CRecompilerOps::CompilePC() + 8; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - if (!DelaySlotEffectsCompare(CRecompilerOps::CompilePC(),Command.rs,Command.rt)) { - Section->m_Jump.PermLoop = true; - } - } - if (Section->IsConst(Command.rs) && Section->IsConst(Command.rt)) - { - __int64 Value1, Value2; - if (Section->Is32Bit(Command.rs)) - { - Value1 = Section->MipsRegLo_S(Command.rs); - } else { - Value1 = Section->MipsReg_S(Command.rs); - } - if (Section->Is32Bit(Command.rt)) - { - Value2 = Section->MipsRegLo_S(Command.rt); - } else { - Value2 = Section->MipsReg_S(Command.rt); - } - if (Value1 == Value2) - { - Section->m_Cont.TargetPC = -1; - } - } - break; - case R4300i_BNE: - case R4300i_BLEZ: - case R4300i_BGTZ: - NextInstruction = DELAY_SLOT; - Section->m_Cont.TargetPC = CRecompilerOps::CompilePC() + 8; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - if (!DelaySlotEffectsCompare(CRecompilerOps::CompilePC(),Command.rs,Command.rt)) { - Section->m_Jump.PermLoop = true; - } - } - break; - case R4300i_ADDI: - case R4300i_ADDIU: - if (Command.rt == 0) { break; } - if (Section->InLoop && Command.rs == Command.rt) { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rs)) { - Section->MipsRegLo(Command.rt) = Section->MipsRegLo(Command.rs) + (short)Command.immediate; - Section->MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; - } else { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SLTI: - if (Command.rt == 0) { break; } - if (Section->IsConst(Command.rs)) { - if (Section->Is64Bit(Command.rs)) { - Section->MipsRegLo(Command.rt) = (Section->MipsReg_S(Command.rs) < (_int64)((short)Command.immediate))?1:0; - } else { - Section->MipsRegLo(Command.rt) = (Section->MipsRegLo_S(Command.rs) < (int)((short)Command.immediate))?1:0; - } - Section->MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; - } else { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_SLTIU: - if (Command.rt == 0) { break; } - if (Section->IsConst(Command.rs)) { - if (Section->Is64Bit(Command.rs)) { - Section->MipsRegLo(Command.rt) = (Section->MipsReg(Command.rs) < (unsigned _int64)((short)Command.immediate))?1:0; - } else { - Section->MipsRegLo(Command.rt) = (Section->MipsRegLo(Command.rs) < (DWORD)((short)Command.immediate))?1:0; - } - Section->MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; - } else { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_LUI: - if (Command.rt == 0) { break; } - Section->MipsRegLo(Command.rt) = ((short)Command.offset << 16); - Section->MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; - break; - case R4300i_ANDI: - if (Command.rt == 0) { break; } - if (Section->InLoop && Command.rs == Command.rt) { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rs)) { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rt) = Section->MipsRegLo(Command.rs) & Command.immediate; - } else { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_ORI: - if (Command.rt == 0) { break; } - if (Section->InLoop && Command.rs == Command.rt) { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rs)) { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rt) = Section->MipsRegLo(Command.rs) | Command.immediate; - } else { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_XORI: - if (Command.rt == 0) { break; } - if (Section->InLoop && Command.rs == Command.rt) { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rs)) { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_CONST_32; - Section->MipsRegLo(Command.rt) = Section->MipsRegLo(Command.rs) ^ Command.immediate; - } else { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_CP0: - switch (Command.rs) { - case R4300i_COP0_MF: - if (Command.rt == 0) { break; } - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - break; - case R4300i_COP0_MT: break; - default: - if ( (Command.rs & 0x10 ) != 0 ) { - switch( Command.funct ) { - case R4300i_COP0_CO_TLBR: break; - case R4300i_COP0_CO_TLBWI: break; - case R4300i_COP0_CO_TLBWR: break; - case R4300i_COP0_CO_TLBP: break; - case R4300i_COP0_CO_ERET: NextInstruction = END_BLOCK; break; - default: -#ifndef EXTERNAL_RELEASE - DisplayError("Unhandled R4300i OpCode in FillSectionInfo\n%s", - R4300iOpcodeName(Command.Hex,CRecompilerOps::CompilePC())); -#endif - NextInstruction = END_BLOCK; - CRecompilerOps::CompilePC() -= 4; - } - } else { -#ifndef EXTERNAL_RELEASE - DisplayError("Unhandled R4300i OpCode in FillSectionInfo 3\n%s", - R4300iOpcodeName(Command.Hex,CRecompilerOps::CompilePC())); -#endif - NextInstruction = END_BLOCK; - CRecompilerOps::CompilePC() -= 4; - } - } - break; - case R4300i_CP1: - switch (Command.fmt) { - case R4300i_COP1_CF: - case R4300i_COP1_MF: - case R4300i_COP1_DMF: - if (Command.rt == 0) { break; } - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - break; - case R4300i_COP1_BC: - switch (Command.ft) { - case R4300i_COP1_BC_BCFL: - case R4300i_COP1_BC_BCTL: - NextInstruction = LIKELY_DELAY_SLOT; - Section->m_Cont.TargetPC = CRecompilerOps::CompilePC() + 8; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - int EffectDelaySlot; - OPCODE NewCommand; - - if (!_MMU->LW_VAddr(CRecompilerOps::CompilePC() + 4, NewCommand.Hex)) { - DisplayError(GS(MSG_FAIL_LOAD_WORD)); - ExitThread(0); - } - - EffectDelaySlot = false; - if (NewCommand.op == R4300i_CP1) { - if (NewCommand.fmt == R4300i_COP1_S && (NewCommand.funct & 0x30) == 0x30 ) { - EffectDelaySlot = true; - } - if (NewCommand.fmt == R4300i_COP1_D && (NewCommand.funct & 0x30) == 0x30 ) { - EffectDelaySlot = true; - } - } - if (!EffectDelaySlot) { - Section->m_Jump.PermLoop = true; - } - } - break; - case R4300i_COP1_BC_BCF: - case R4300i_COP1_BC_BCT: - NextInstruction = DELAY_SLOT; - Section->m_Cont.TargetPC = CRecompilerOps::CompilePC() + 8; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - int EffectDelaySlot; - OPCODE NewCommand; - - if (!_MMU->LW_VAddr(CRecompilerOps::CompilePC() + 4, NewCommand.Hex)) { - DisplayError(GS(MSG_FAIL_LOAD_WORD)); - ExitThread(0); - } - - EffectDelaySlot = false; - if (NewCommand.op == R4300i_CP1) { - if (NewCommand.fmt == R4300i_COP1_S && (NewCommand.funct & 0x30) == 0x30 ) { - EffectDelaySlot = true; - } - if (NewCommand.fmt == R4300i_COP1_D && (NewCommand.funct & 0x30) == 0x30 ) { - EffectDelaySlot = true; - } - } - if (!EffectDelaySlot) { - Section->m_Jump.PermLoop = true; - } - } - break; - } - break; - case R4300i_COP1_MT: break; - case R4300i_COP1_DMT: break; - case R4300i_COP1_CT: break; - case R4300i_COP1_S: break; - case R4300i_COP1_D: break; - case R4300i_COP1_W: break; - case R4300i_COP1_L: break; - default: -#ifndef EXTERNAL_RELEASE - DisplayError("Unhandled R4300i OpCode in FillSectionInfo 2\n%s", - R4300iOpcodeName(Command.Hex,CRecompilerOps::CompilePC())); -#endif - NextInstruction = END_BLOCK; - CRecompilerOps::CompilePC() -= 4; - } - break; - case R4300i_BEQL: - case R4300i_BNEL: - case R4300i_BLEZL: - case R4300i_BGTZL: - NextInstruction = LIKELY_DELAY_SLOT; - Section->m_Cont.TargetPC = CRecompilerOps::CompilePC() + 8; - Section->m_Jump.TargetPC = CRecompilerOps::CompilePC() + ((short)Command.offset << 2) + 4; - if (CRecompilerOps::CompilePC() == Section->m_Jump.TargetPC) { - if (!DelaySlotEffectsCompare(CRecompilerOps::CompilePC(),Command.rs,Command.rt)) { - Section->m_Jump.PermLoop = true; - } - } - break; - case R4300i_DADDI: - case R4300i_DADDIU: - if (Command.rt == 0) { break; } - if (Section->InLoop && Command.rs == Command.rt) { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - if (Section->IsConst(Command.rs)) { - if (Section->Is64Bit(Command.rs)) { - int imm32 = (short)Opcode.immediate; - __int64 imm64 = imm32; - Section->MipsReg_S(Command.rt) = Section->MipsRegLo_S(Command.rs) + imm64; - } else { - Section->MipsReg_S(Command.rt) = Section->MipsRegLo_S(Command.rs) + (short)Command.immediate; - } - Section->MipsRegState(Command.rt) = CRegInfo::STATE_CONST_64; - } else { - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - } - break; - case R4300i_LDR: - case R4300i_LDL: - case R4300i_LB: - case R4300i_LH: - case R4300i_LWL: - case R4300i_LW: - case R4300i_LWU: - case R4300i_LL: - case R4300i_LBU: - case R4300i_LHU: - case R4300i_LWR: - case R4300i_SC: - if (Command.rt == 0) { break; } - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - break; - case R4300i_SB: break; - case R4300i_SH: break; - case R4300i_SWL: break; - case R4300i_SW: break; - case R4300i_SWR: break; - case R4300i_SDL: break; - case R4300i_SDR: break; - case R4300i_CACHE: break; - case R4300i_LWC1: break; - case R4300i_SWC1: break; - case R4300i_LDC1: break; - case R4300i_LD: - if (Command.rt == 0) { break; } - Section->MipsRegState(Command.rt) = CRegInfo::STATE_UNKNOWN; - break; - case R4300i_SDC1: break; - case R4300i_SD: break; - default: - NextInstruction = END_BLOCK; - CRecompilerOps::CompilePC() -= 4; - if (Command.Hex == 0x7C1C97C0) { break; } - if (Command.Hex == 0x7FFFFFFF) { break; } - if (Command.Hex == 0xF1F3F5F7) { break; } - if (Command.Hex == 0xC1200000) { break; } - if (Command.Hex == 0x4C5A5353) { break; } -#ifndef EXTERNAL_RELEASE - DisplayError("Unhandled R4300i OpCode in FillSectionInfo 1\n%s\n%X", - R4300iOpcodeName(Command.Hex,CRecompilerOps::CompilePC()),Command.Hex); -#endif - } - -// if (CRecompilerOps::CompilePC() == 0x8005E4B8) { -//CPU_Message("%X: %s %s = %d",CRecompilerOps::CompilePC(),R4300iOpcodeName(Command.Hex,CRecompilerOps::CompilePC()), -// CRegName::GPR[8],Section->MipsRegState(8)); -//_asm int 3 -// } - switch (NextInstruction) { - case NORMAL: - CRecompilerOps::CompilePC() += 4; - break; - case DELAY_SLOT: - NextInstruction = DELAY_SLOT_DONE; - CRecompilerOps::CompilePC() += 4; - break; - case LIKELY_DELAY_SLOT: - if (Section->m_Cont.TargetPC == Section->m_Jump.TargetPC) - { - Section->m_Jump.RegSet = Section->RegWorking; - Section->m_Cont.DoneDelaySlot = false; - Section->m_Cont.RegSet = Section->RegWorking; - Section->m_Cont.DoneDelaySlot = true; - NextInstruction = END_BLOCK; - } else { - Section->m_Cont.RegSet = Section->RegWorking; - Section->m_Cont.DoneDelaySlot = true; - NextInstruction = LIKELY_DELAY_SLOT_DONE; - CRecompilerOps::CompilePC() += 4; - } - break; - case DELAY_SLOT_DONE: - Section->m_Cont.RegSet = Section->RegWorking; - Section->m_Jump.RegSet = Section->RegWorking; - Section->m_Cont.DoneDelaySlot = true; - Section->m_Jump.DoneDelaySlot = true; - NextInstruction = END_BLOCK; - break; - case LIKELY_DELAY_SLOT_DONE: - Section->m_Jump.RegSet = Section->RegWorking; - Section->m_Jump.DoneDelaySlot = true; - NextInstruction = END_BLOCK; - break; - } - if ((CRecompilerOps::CompilePC() & 0xFFFFF000) != (Section->StartPC & 0xFFFFF000)) { - if (NextInstruction != END_BLOCK && NextInstruction != NORMAL) { - // DisplayError("Branch running over delay slot ???\nNextInstruction == %d",NextInstruction); - Section->m_Cont.TargetPC = (DWORD)-1; - Section->m_Jump.TargetPC = (DWORD)-1; - } - NextInstruction = END_BLOCK; - CRecompilerOps::CompilePC() -= 4; - } - } while (NextInstruction != END_BLOCK); - - if (Section->m_Cont.TargetPC != (DWORD)-1) { - if ((Section->m_Cont.TargetPC & 0xFFFFF000) != (Section->StartPC & 0xFFFFF000)) { - Section->m_Cont.TargetPC = (DWORD)-1; - } - } - if (Section->m_Jump.TargetPC != (DWORD)-1) { - if (Section->m_Jump.TargetPC < Section->BlockInfo->StartVAddr) - { - Section->m_Jump.TargetPC = (DWORD)-1; - } - if ((Section->m_Jump.TargetPC & 0xFFFFF000) != (Section->StartPC & 0xFFFFF000)) { - Section->m_Jump.TargetPC = (DWORD)-1; - } - } -#endif - return true; -} - void CRecompiler::RecompilerMain_ChangeMemory ( void ) { _Notify->BreakPoint(__FILE__,__LINE__); @@ -2013,3 +889,16 @@ void CRecompiler::ClearRecompCode_Virt(DWORD Address, int length,REMOVE_REASON R _Notify->BreakPoint(__FILE__,__LINE__); } } + +void CRecompiler::ResetMemoryStackPos( void ) +{ + if (_MMU == NULL || _Reg == NULL) + { + _Notify->BreakPoint(__FILE__,__LINE__); + } + if (_Reg->m_GPR[29].UW[0] < 0x80000000 || _Reg->m_GPR[29].UW[0] >= 0xC0000000) + { + _Notify->BreakPoint(__FILE__,__LINE__); + } + m_MemoryStack = (DWORD)(_MMU->Rdram() + (_Reg->m_GPR[29].UW[0] & 0x1FFFFFFF)); +} diff --git a/Source/Project64/N64 System/Recompiler/Recompiler Class.h b/Source/Project64/N64 System/Recompiler/Recompiler Class.h index 813ff3942..7e93330be 100644 --- a/Source/Project64/N64 System/Recompiler/Recompiler Class.h +++ b/Source/Project64/N64 System/Recompiler/Recompiler Class.h @@ -31,11 +31,16 @@ public: //Self modifying code methods void ClearRecompCode_Virt ( DWORD VirtualAddress, int length, REMOVE_REASON Reason ); void ClearRecompCode_Phys ( DWORD PhysicalAddress, int length, REMOVE_REASON Reason ); + + void ResetMemoryStackPos ( void ); + + inline DWORD & MemoryStackPos ( void ) { return m_MemoryStack; } private: CCompiledFuncList m_Functions; CProfiling & m_Profile; bool & m_EndEmulation; + DWORD m_MemoryStack; //Quick access to registers DWORD & PROGRAM_COUNTER; @@ -44,16 +49,9 @@ private: bool Compiler4300iBlock ( CCompiledFunc * info ); // Compiling code - bool AnalyseBlock ( CCodeBlock & BlockInfo ); bool CreateSectionLinkage ( CCodeSection * Section ); - void DetermineLoop ( CCodeSection * Section, DWORD Test, DWORD Test2, DWORD TestID); bool DisplaySectionInformation (CCodeSection * Section, DWORD ID, DWORD Test); - bool FixConstants ( CCodeSection * Section, DWORD Test ); bool InheritParentInfo ( CCodeSection * Section ); - void InheritConstants ( CCodeSection * Section ); - bool FillSectionInfo ( CCodeSection * Section, STEP_TYPE StartStepType ); - void SyncRegState ( CCodeSection * Section, CRegInfo * SyncTo ); - CCodeSection * ExistingSection( CCodeSection * StartSection, DWORD Addr, DWORD Test); // Main loops for the different look up methods void RecompilerMain_VirtualTable ( void ); diff --git a/Source/Project64/N64 System/Recompiler/Recompiler Ops.cpp b/Source/Project64/N64 System/Recompiler/Recompiler Ops.cpp index a05552bd7..735f520a3 100644 --- a/Source/Project64/N64 System/Recompiler/Recompiler Ops.cpp +++ b/Source/Project64/N64 System/Recompiler/Recompiler Ops.cpp @@ -1103,11 +1103,9 @@ void CRecompilerOps::ADDI (void) { if (m_Opcode.rt == 0) { return; } -#ifdef tofix - if (SPHack && m_Opcode.rs == 29 && m_Opcode.rt == 29) { - AddConstToX86Reg(Map_MemoryStack(m_Section, x86_Any, true),(short)m_Opcode.immediate); + if (bFastSP() && m_Opcode.rs == 29 && m_Opcode.rt == 29) { + AddConstToX86Reg(Map_MemoryStack(x86_Any, true),(short)m_Opcode.immediate); } -#endif if (IsConst(m_Opcode.rs)) { if (IsMapped(m_Opcode.rt)) { UnMap_GPR(m_Opcode.rt, FALSE); } @@ -1117,12 +1115,13 @@ void CRecompilerOps::ADDI (void) { Map_GPR_32bit(m_Opcode.rt,TRUE,m_Opcode.rs); AddConstToX86Reg(cMipsRegMapLo(m_Opcode.rt),(short)m_Opcode.immediate); } -#ifdef tofix - if (SPHack && m_Opcode.rt == 29 && m_Opcode.rs != 29) { + if (bFastSP() && m_Opcode.rt == 29 && m_Opcode.rs != 29) { ResetX86Protection(); +_Notify->BreakPoint(__FILE__,__LINE__); +#ifdef tofix _MMU->ResetMemoryStack(m_Section); - } #endif + } } void CRecompilerOps::ADDIU (void) { @@ -1130,15 +1129,13 @@ void CRecompilerOps::ADDIU (void) { if (m_Opcode.rt == 0 || (m_Opcode.immediate == 0 && m_Opcode.rs == m_Opcode.rt)) { return; } -#ifdef tofix - if (SPHack) + if (bFastSP()) { if (m_Opcode.rs == 29 && m_Opcode.rt == 29) { - AddConstToX86Reg(Map_MemoryStack(m_Section, x86_Any, TRUE),(short)m_Opcode.immediate); + AddConstToX86Reg(Map_MemoryStack(x86_Any, TRUE),(short)m_Opcode.immediate); } } -#endif if (IsConst(m_Opcode.rs)) { if (IsMapped(m_Opcode.rt)) { UnMap_GPR(m_Opcode.rt, FALSE); } @@ -1149,12 +1146,10 @@ void CRecompilerOps::ADDIU (void) { AddConstToX86Reg(cMipsRegMapLo(m_Opcode.rt),(short)m_Opcode.immediate); } -#ifdef tofix - if (SPHack && m_Opcode.rt == 29 && m_Opcode.rs != 29) { + if (bFastSP() && m_Opcode.rt == 29 && m_Opcode.rs != 29) { ResetX86Protection(); - _MMU->ResetMemoryStack(m_Section); + _MMU->ResetMemoryStack(); } -#endif } void CRecompilerOps::SLTIU (void) { @@ -1211,22 +1206,7 @@ void CRecompilerOps::SLTIU (void) { *((BYTE *)(Jump))=(BYTE)(m_RecompPos - Jump - 1); SetbVariable(&m_BranchCompare,"m_BranchCompare"); Map_GPR_32bit(m_Opcode.rt,FALSE, -1); - MoveVariableToX86reg(&m_BranchCompare,"m_BranchCompare",cMipsRegMapLo(m_Opcode.rt)); - - - /*SetbVariable(&m_BranchCompare,"m_BranchCompare"); - JmpLabel8("Continue",0); - Jump[1] = m_RecompPos - 1; - CPU_Message(""); - CPU_Message(" Low Compare:"); - *((BYTE *)(Jump[0]))=(BYTE)(m_RecompPos - Jump[0] - 1); - CompConstToVariable((short)m_Opcode.immediate,&_GPR[m_Opcode.rs].W[0],CRegName::GPR_Lo[m_Opcode.rs]); - SetbVariable(&m_BranchCompare,"m_BranchCompare"); - CPU_Message(""); - CPU_Message(" Continue:"); - *((BYTE *)(Jump[1]))=(BYTE)(m_RecompPos - Jump[1] - 1); - Map_GPR_32bit(m_Opcode.rt,FALSE, -1); - MoveVariableToX86reg(&m_BranchCompare,"m_BranchCompare",cMipsRegMapLo(m_Opcode.rt));*/ + MoveVariableToX86reg(&m_BranchCompare,"m_BranchCompare",cMipsRegMapLo(m_Opcode.rt)); } } @@ -1369,19 +1349,18 @@ void CRecompilerOps::LUI (void) { CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC)); if (m_Opcode.rt == 0) { return;} -#ifdef tofix - if (SPHack && m_Opcode.rt == 29) { - x86Reg Reg = Map_MemoryStack(m_Section, x86_Any, false); + if (bFastSP() && m_Opcode.rt == 29) { + x86Reg Reg = Map_MemoryStack(x86_Any, false); DWORD Address; - TranslateVaddr (((short)m_Opcode.offset << 16), &Address); - if (x86reg < 0) { - MoveConstToVariable((DWORD)(Address + RDRAM), g_MemoryStack, "MemoryStack"); + _TransVaddr->TranslateVaddr(((short)m_Opcode.offset << 16), Address); + if (Reg < 0) { + MoveConstToVariable((DWORD)(Address + _MMU->Rdram()), &(_Recompiler->MemoryStackPos()), "MemoryStack"); } else { - MoveConstToX86reg((DWORD)(Address + RDRAM), x86reg); + MoveConstToX86reg((DWORD)(Address + _MMU->Rdram()), Reg); } } -#endif + UnMap_GPR(m_Opcode.rt, FALSE); MipsRegLo(m_Opcode.rt) = ((short)m_Opcode.offset << 16); MipsRegState(m_Opcode.rt) = CRegInfo::STATE_CONST_32; @@ -2658,12 +2637,10 @@ void CRecompilerOps::SPECIAL_OR (void) { OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[1],CRegName::GPR_Hi[m_Opcode.rs],MipsRegMapHi(m_Opcode.rd)); OrVariableToX86Reg(&_GPR[m_Opcode.rs].W[0],CRegName::GPR_Lo[m_Opcode.rs],cMipsRegMapLo(m_Opcode.rd)); } -#ifdef tofix - if (SPHack && m_Opcode.rd == 29) { + if (bFastSP() && m_Opcode.rd == 29) { ResetX86Protection(); - _MMU->ResetMemoryStack(m_Section); + _MMU->ResetMemoryStack(); } -#endif } void CRecompilerOps::SPECIAL_XOR (void) { @@ -3942,7 +3919,7 @@ void CRecompilerOps::COP1_CT(void) { BeforeCallDirect(m_RegWorkingSet); Call_Direct(ChangeDefaultRoundingModel, "ChangeDefaultRoundingModel"); AfterCallDirect(m_RegWorkingSet); - m_RegWorkingSet.CurrentRoundingModel() = CRegInfo::RoundUnknown; + m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); } /************************** COP1: S functions ************************/ @@ -4688,7 +4665,7 @@ void CRecompilerOps::BeforeCallDirect ( CRegInfo & RegSet ) void CRecompilerOps::AfterCallDirect ( CRegInfo & RegSet ) { Popad(); - RegSet.CurrentRoundingModel() = CRegInfo::RoundUnknown; + RegSet.SetRoundingModel(CRegInfo::RoundUnknown); } void CRecompilerOps::EnterCodeBlock ( void ) diff --git a/Source/Project64/N64 System/Recompiler/Recompiler Ops.h b/Source/Project64/N64 System/Recompiler/Recompiler Ops.h index 1bfb275bb..1e4edbc2c 100644 --- a/Source/Project64/N64 System/Recompiler/Recompiler Ops.h +++ b/Source/Project64/N64 System/Recompiler/Recompiler Ops.h @@ -2,7 +2,8 @@ class CCodeSection; class CRecompilerOps : protected CX86Ops, - protected CSystemRegisters + protected CSystemRegisters, + protected CRecompilerSettings { protected: enum BRANCH_TYPE @@ -281,6 +282,10 @@ protected: { m_RegWorkingSet.Map_GPR_64bit(Reg,MipsRegToLoad); } + static inline x86Reg Map_MemoryStack ( x86Reg Reg, bool bMapRegister ) + { + return m_RegWorkingSet.Map_MemoryStack(Reg,bMapRegister); + } static inline x86Reg Map_TempReg ( x86Reg Reg, int MipsReg, BOOL LoadHiWord ) { return m_RegWorkingSet.Map_TempReg(Reg,MipsReg,LoadHiWord); diff --git a/Source/Project64/N64 System/Recompiler/Reg Info.cpp b/Source/Project64/N64 System/Recompiler/Reg Info.cpp index 2657488bb..4b9660901 100644 --- a/Source/Project64/N64 System/Recompiler/Reg Info.cpp +++ b/Source/Project64/N64 System/Recompiler/Reg Info.cpp @@ -34,16 +34,16 @@ void CRegInfo::Initilize ( void ) x86fpu_RoundingModel[count] = RoundDefault; } Fpu_Used = false; - RoundingModel = RoundUnknown; + m_RoundingModel = RoundUnknown; } void CRegInfo::FixRoundModel(FPU_ROUND RoundMethod ) { - if (CurrentRoundingModel() == RoundMethod) + if (GetRoundingModel() == RoundMethod) { return; } - CPU_Message(" FixRoundModel: CurrentRoundingModel: %s targetRoundModel: %s",RoundingModelName(CurrentRoundingModel()),RoundingModelName(RoundMethod)); + CPU_Message(" FixRoundModel: CurrentRoundingModel: %s targetRoundModel: %s",RoundingModelName(GetRoundingModel()),RoundingModelName(RoundMethod)); m_fpuControl = 0; fpuStoreControl(&m_fpuControl, "m_fpuControl"); @@ -57,7 +57,7 @@ void CRegInfo::FixRoundModel(FPU_ROUND RoundMethod ) MoveVariableToX86reg(&_Reg->m_RoundingModel,"m_RoundingModel", RoundReg); ShiftLeftSignImmed(RoundReg,2); OrX86RegToX86Reg(reg,RoundReg); - x86Protected(RoundReg) = false; + SetX86Protected(RoundReg,false); } else { switch (RoundMethod) { case RoundTruncate: OrConstToX86Reg(0x0C00, reg); break; @@ -69,9 +69,9 @@ void CRegInfo::FixRoundModel(FPU_ROUND RoundMethod ) } } MoveX86regToVariable(reg, &m_fpuControl, "m_fpuControl"); - x86Protected(reg) = false; + SetX86Protected(reg,false); fpuLoadControl(&m_fpuControl, "m_fpuControl"); - CurrentRoundingModel() = RoundMethod; + SetRoundingModel(RoundMethod); } void CRegInfo::ChangeFPURegFormat (int Reg, FPU_STATE OldFormat, FPU_STATE NewFormat, FPU_ROUND RoundingModel) @@ -102,11 +102,11 @@ void CRegInfo::ChangeFPURegFormat (int Reg, FPU_STATE OldFormat, FPU_STATE NewFo void CRegInfo::Load_FPR_ToTop ( int Reg, int RegToLoad, FPU_STATE Format) { - if (CurrentRoundingModel() != RoundDefault) + if (GetRoundingModel() != RoundDefault) { FixRoundModel(RoundDefault); } - CPU_Message("CurrentRoundingModel: %s FpuRoundingModel(StackTopPos()): %s",RoundingModelName(CurrentRoundingModel()),RoundingModelName(FpuRoundingModel(StackTopPos()))); + CPU_Message("CurrentRoundingModel: %s FpuRoundingModel(StackTopPos()): %s",RoundingModelName(GetRoundingModel()),RoundingModelName(FpuRoundingModel(StackTopPos()))); int i; if (RegToLoad < 0) { DisplayError("Load_FPR_ToTop\nRegToLoad < 0 ???"); return; } @@ -246,7 +246,7 @@ void CRegInfo::Load_FPR_ToTop ( int Reg, int RegToLoad, FPU_STATE Format) DisplayError("Load_FPR_ToTop\nUnkown format to load %d",Format); #endif } - x86Protected(TempReg) = FALSE; + SetX86Protected(TempReg,FALSE); FpuRoundingModel(StackTopPos()) = RoundDefault; x86fpu_MappedTo[StackTopPos()] = Reg; x86fpu_State[StackTopPos()] = Format; @@ -268,12 +268,12 @@ CRegInfo::x86FpuValues CRegInfo::StackPosition (int Reg) CX86Ops::x86Reg CRegInfo::FreeX86Reg ( void ) { - if (x86Mapped(x86_EDI) == NotMapped && !x86Protected(x86_EDI)) { return x86_EDI; } - if (x86Mapped(x86_ESI) == NotMapped && !x86Protected(x86_ESI)) { return x86_ESI; } - if (x86Mapped(x86_EBX) == NotMapped && !x86Protected(x86_EBX)) { return x86_EBX; } - if (x86Mapped(x86_EAX) == NotMapped && !x86Protected(x86_EAX)) { return x86_EAX; } - if (x86Mapped(x86_EDX) == NotMapped && !x86Protected(x86_EDX)) { return x86_EDX; } - if (x86Mapped(x86_ECX) == NotMapped && !x86Protected(x86_ECX)) { return x86_ECX; } + if (GetX86Mapped(x86_EDI) == NotMapped && !GetX86Protected(x86_EDI)) { return x86_EDI; } + if (GetX86Mapped(x86_ESI) == NotMapped && !GetX86Protected(x86_ESI)) { return x86_ESI; } + if (GetX86Mapped(x86_EBX) == NotMapped && !GetX86Protected(x86_EBX)) { return x86_EBX; } + if (GetX86Mapped(x86_EAX) == NotMapped && !GetX86Protected(x86_EAX)) { return x86_EAX; } + if (GetX86Mapped(x86_EDX) == NotMapped && !GetX86Protected(x86_EDX)) { return x86_EDX; } + if (GetX86Mapped(x86_ECX) == NotMapped && !GetX86Protected(x86_ECX)) { return x86_ECX; } x86Reg Reg = UnMap_TempReg(); if (Reg != x86_Unknown) { return Reg; } @@ -283,7 +283,7 @@ CX86Ops::x86Reg CRegInfo::FreeX86Reg ( void ) for (count = 0; count < 10; count ++) { - MapCount[count] = x86MapOrder((x86Reg)count); + MapCount[count] = GetX86MapOrder((x86Reg)count); MapReg[count] = (x86Reg)count; } for (count = 0; count < 10; count ++) { @@ -308,14 +308,14 @@ CX86Ops::x86Reg CRegInfo::FreeX86Reg ( void ) x86Reg StackReg = x86_Unknown; for (count = 0; count < 10; count ++) { - if (MapCount[count] > 0 && x86Mapped(MapReg[count]) != Stack_Mapped) + if (MapCount[count] > 0 && GetX86Mapped(MapReg[count]) != Stack_Mapped) { if (UnMap_X86reg((x86Reg)MapReg[count])) { return (x86Reg)MapReg[count]; } } - if (x86Mapped(MapReg[count]) == Stack_Mapped) { StackReg = MapReg[count]; } + if (GetX86Mapped(MapReg[count]) == Stack_Mapped) { StackReg = MapReg[count]; } } if (StackReg != x86_Unknown) { UnMap_X86reg(StackReg); @@ -328,10 +328,10 @@ CX86Ops::x86Reg CRegInfo::FreeX86Reg ( void ) CX86Ops::x86Reg CRegInfo::Free8BitX86Reg ( void ) { - if (x86Mapped(x86_EBX) == NotMapped && !x86Protected(x86_EBX)) {return x86_EBX; } - if (x86Mapped(x86_EAX) == NotMapped && !x86Protected(x86_EAX)) {return x86_EAX; } - if (x86Mapped(x86_EDX) == NotMapped && !x86Protected(x86_EDX)) {return x86_EDX; } - if (x86Mapped(x86_ECX) == NotMapped && !x86Protected(x86_ECX)) {return x86_ECX; } + if (GetX86Mapped(x86_EBX) == NotMapped && !GetX86Protected(x86_EBX)) {return x86_EBX; } + if (GetX86Mapped(x86_EAX) == NotMapped && !GetX86Protected(x86_EAX)) {return x86_EAX; } + if (GetX86Mapped(x86_EDX) == NotMapped && !GetX86Protected(x86_EDX)) {return x86_EDX; } + if (GetX86Mapped(x86_ECX) == NotMapped && !GetX86Protected(x86_ECX)) {return x86_ECX; } x86Reg Reg = UnMap_8BitTempReg(); @@ -339,7 +339,7 @@ CX86Ops::x86Reg CRegInfo::Free8BitX86Reg ( void ) int count, MapCount[10], MapReg[10]; for (count = 0; count < 10; count ++) { - MapCount[count] = x86MapOrder((x86Reg)count); + MapCount[count] = GetX86MapOrder((x86Reg)count); MapReg[count] = count; } for (count = 0; count < 10; count ++) { @@ -377,9 +377,9 @@ CX86Ops::x86Reg CRegInfo::UnMap_8BitTempReg (void ) for (count = 0; count < 10; count ++) { if (!Is8BitReg((x86Reg)count)) { continue; } if (MipsRegState((x86Reg)count) == Temp_Mapped) { - if (x86Protected((x86Reg)count) == FALSE) { + if (GetX86Protected((x86Reg)count) == FALSE) { CPU_Message(" regcache: unallocate %s from temp storage",x86_Name((x86Reg)count)); - x86Mapped((x86Reg)count) = CRegInfo::NotMapped; + SetX86Mapped((x86Reg)count, CRegInfo::NotMapped); return (x86Reg)count; } } @@ -387,6 +387,67 @@ CX86Ops::x86Reg CRegInfo::UnMap_8BitTempReg (void ) return x86_Unknown; } +CRegInfo::x86Reg CRegInfo::Map_MemoryStack ( x86Reg Reg, bool bMapRegister) +{ + x86Reg CurrentMap = x86_Unknown; + if (GetX86Mapped(x86_EAX) == Stack_Mapped) { CurrentMap = x86_EAX; } + else if (GetX86Mapped(x86_EBX) == Stack_Mapped) { CurrentMap = x86_EBX; } + else if (GetX86Mapped(x86_ECX) == Stack_Mapped) { CurrentMap = x86_ECX; } + else if (GetX86Mapped(x86_EDX) == Stack_Mapped) { CurrentMap = x86_EDX; } + else if (GetX86Mapped(x86_ESI) == Stack_Mapped) { CurrentMap = x86_ESI; } + else if (GetX86Mapped(x86_EDI) == Stack_Mapped) { CurrentMap = x86_EDI; } + else if (GetX86Mapped(x86_EBP) == Stack_Mapped) { CurrentMap = x86_EBP; } + else if (GetX86Mapped(x86_ESP) == Stack_Mapped) { CurrentMap = x86_ESP; } + + if (!bMapRegister) + { + //if not mapping then just return what the current mapping is + return CurrentMap; + } + + if (CurrentMap != x86_Unknown && CurrentMap == Reg) + { + //already mapped to correct reg + return CurrentMap; + } + // map a register + if (Reg == x86_Any) + { + if (CurrentMap != x86_Unknown) + { + return CurrentMap; + } + Reg = FreeX86Reg(); + if (Reg == x86_Unknown) + { + DisplayError("Map_MemoryStack\n\nOut of registers"); + BreakPoint(__FILE__,__LINE__); + } + SetX86Mapped(Reg,CRegInfo::Stack_Mapped); + CPU_Message(" regcache: allocate %s as Memory Stack",x86_Name(Reg)); + MoveVariableToX86reg(&_Recompiler->MemoryStackPos(),"MemoryStack",Reg); + return Reg; + } + + _Notify->BreakPoint(__FILE__,__LINE__); +#ifdef tofix + //move to a register/allocate register + UnMap_X86reg(Section, Reg); + if (CurrentMap >= 0) + { + CPU_Message(" regcache: change allocation of Memory Stack from %s to %s",x86_Name(CurrentMap),x86_Name(Reg)); + Section->GetX86Mapped(Reg) = CRegInfo::Stack_Mapped; + Section->GetX86Mapped(CurrentMap) = CRegInfo::NotMapped; + MoveX86RegToX86Reg(CurrentMap,Reg); + } else { + Section->GetX86Mapped(Reg) = CRegInfo::Stack_Mapped; + CPU_Message(" regcache: allocate %s as Memory Stack",x86_Name(Reg)); + MoveVariableToX86reg(g_MemoryStack,"MemoryStack",Reg); + } +#endif + return Reg; +} + void CRegInfo::Map_GPR_32bit (int MipsReg, BOOL SignValue, int MipsRegToLoad) { int count; @@ -412,19 +473,21 @@ void CRegInfo::Map_GPR_32bit (int MipsReg, BOOL SignValue, int MipsRegToLoad) } else { if (Is64Bit(MipsReg)) { CPU_Message(" regcache: unallocate %s from high 32bit of %s",x86_Name(MipsRegMapHi(MipsReg)),CRegName::GPR_Hi[MipsReg]); - x86MapOrder(MipsRegMapHi(MipsReg)) = 0; - x86Mapped(MipsRegMapHi(MipsReg)) = NotMapped; - x86Protected(MipsRegMapHi(MipsReg)) = FALSE; + SetX86MapOrder(MipsRegMapHi(MipsReg),0); + SetX86Mapped(MipsRegMapHi(MipsReg),NotMapped); + SetX86Protected(MipsRegMapHi(MipsReg),FALSE); MipsRegHi(MipsReg) = 0; } Reg = MipsRegMapLo(MipsReg); } - for (count = 0; count < 10; count ++) { - if (x86MapOrder((x86Reg)count) > 0) { - x86MapOrder((x86Reg)count) += 1; + for (count = 0; count < 10; count ++) + { + DWORD Count = GetX86MapOrder((x86Reg)count); + if ( Count > 0) { + SetX86MapOrder((x86Reg)count,Count + 1); } } - x86MapOrder(Reg) = 1; + SetX86MapOrder(Reg,1); if (MipsRegToLoad > 0) { if (IsUnknown(MipsRegToLoad)) { @@ -439,8 +502,8 @@ void CRegInfo::Map_GPR_32bit (int MipsReg, BOOL SignValue, int MipsRegToLoad) } else if (MipsRegToLoad == 0) { XorX86RegToX86Reg(Reg,Reg); } - x86Mapped(Reg) = GPR_Mapped; - x86Protected(Reg) = TRUE; + SetX86Mapped(Reg,GPR_Mapped); + SetX86Protected(Reg,TRUE); MipsRegMapLo(MipsReg) = Reg; MipsRegState(MipsReg) = SignValue ? STATE_MAPPED_32_SIGN : STATE_MAPPED_32_ZERO; } @@ -461,32 +524,37 @@ void CRegInfo::Map_GPR_64bit ( int MipsReg, int MipsRegToLoad) if (IsUnknown(MipsReg) || IsConst(MipsReg)) { x86Hi = FreeX86Reg(); if (x86Hi < 0) { DisplayError("Map_GPR_64bit\n\nOut of registers"); return; } - x86Protected(x86Hi) = TRUE; + SetX86Protected(x86Hi,TRUE); x86lo = FreeX86Reg(); if (x86lo < 0) { DisplayError("Map_GPR_64bit\n\nOut of registers"); return; } - x86Protected(x86lo) = TRUE; + SetX86Protected(x86lo,TRUE); CPU_Message(" regcache: allocate %s to hi word of %s",x86_Name(x86Hi),CRegName::GPR[MipsReg]); CPU_Message(" regcache: allocate %s to low word of %s",x86_Name(x86lo),CRegName::GPR[MipsReg]); } else { x86lo = MipsRegMapLo(MipsReg); if (Is32Bit(MipsReg)) { - x86Protected(x86lo) = TRUE; + SetX86Protected(x86lo,TRUE); x86Hi = FreeX86Reg(); if (x86Hi < 0) { DisplayError("Map_GPR_64bit\n\nOut of registers"); return; } - x86Protected(x86Hi) = TRUE; + SetX86Protected(x86Hi,TRUE); } else { x86Hi = MipsRegMapHi(MipsReg); } } - for (count = 0; count < 10; count ++) { - if (x86MapOrder((x86Reg)count) > 0) { x86MapOrder((x86Reg)count) += 1; } + for (count = 0; count < 10; count ++) + { + int MapOrder = GetX86MapOrder((x86Reg)count); + if (MapOrder > 0) + { + SetX86MapOrder((x86Reg)count,MapOrder + 1); + } } - x86MapOrder(x86Hi) = 1; - x86MapOrder(x86lo) = 1; + SetX86MapOrder(x86Hi,1); + SetX86MapOrder(x86lo,1); if (MipsRegToLoad > 0) { if (IsUnknown(MipsRegToLoad)) { MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[1],CRegName::GPR_Hi[MipsRegToLoad],x86Hi); @@ -525,8 +593,8 @@ CPU_Message("Map_GPR_64bit 11"); XorX86RegToX86Reg(x86Hi,x86Hi); XorX86RegToX86Reg(x86lo,x86lo); } - x86Mapped(x86Hi) = GPR_Mapped; - x86Mapped(x86lo) = GPR_Mapped; + SetX86Mapped(x86Hi,GPR_Mapped); + SetX86Mapped(x86lo,GPR_Mapped); MipsRegMapHi(MipsReg) = x86Hi; MipsRegMapLo(MipsReg) = x86lo; MipsRegState(MipsReg) = STATE_MAPPED_64; @@ -538,14 +606,14 @@ CX86Ops::x86Reg CRegInfo::Map_TempReg (CX86Ops::x86Reg Reg, int MipsReg, BOOL Lo if (Reg == x86_Any) { - if (x86Mapped(x86_EAX) == Temp_Mapped && !x86Protected(x86_EAX)) { Reg = x86_EAX; } - else if (x86Mapped(x86_EBX) == Temp_Mapped && !x86Protected(x86_EBX)) { Reg = x86_EBX; } - else if (x86Mapped(x86_ECX) == Temp_Mapped && !x86Protected(x86_ECX)) { Reg = x86_ECX; } - else if (x86Mapped(x86_EDX) == Temp_Mapped && !x86Protected(x86_EDX)) { Reg = x86_EDX; } - else if (x86Mapped(x86_ESI) == Temp_Mapped && !x86Protected(x86_ESI)) { Reg = x86_ESI; } - else if (x86Mapped(x86_EDI) == Temp_Mapped && !x86Protected(x86_EDI)) { Reg = x86_EDI; } - else if (x86Mapped(x86_EBP) == Temp_Mapped && !x86Protected(x86_EBP)) { Reg = x86_EBP; } - else if (x86Mapped(x86_ESP) == Temp_Mapped && !x86Protected(x86_ESP)) { Reg = x86_ESP; } + if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; } + else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; } + else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; } + else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; } + else if (GetX86Mapped(x86_ESI) == Temp_Mapped && !GetX86Protected(x86_ESI)) { Reg = x86_ESI; } + else if (GetX86Mapped(x86_EDI) == Temp_Mapped && !GetX86Protected(x86_EDI)) { Reg = x86_EDI; } + else if (GetX86Mapped(x86_EBP) == Temp_Mapped && !GetX86Protected(x86_EBP)) { Reg = x86_EBP; } + else if (GetX86Mapped(x86_ESP) == Temp_Mapped && !GetX86Protected(x86_ESP)) { Reg = x86_ESP; } if (Reg == x86_Any) { Reg = FreeX86Reg(); @@ -559,10 +627,10 @@ CX86Ops::x86Reg CRegInfo::Map_TempReg (CX86Ops::x86Reg Reg, int MipsReg, BOOL Lo } else if (Reg == x86_Any8Bit) { - if (x86Mapped(x86_EAX) == Temp_Mapped && !x86Protected(x86_EAX)) { Reg = x86_EAX; } - else if (x86Mapped(x86_EBX) == Temp_Mapped && !x86Protected(x86_EBX)) { Reg = x86_EBX; } - else if (x86Mapped(x86_ECX) == Temp_Mapped && !x86Protected(x86_ECX)) { Reg = x86_ECX; } - else if (x86Mapped(x86_EDX) == Temp_Mapped && !x86Protected(x86_EDX)) { Reg = x86_EDX; } + if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; } + else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; } + else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; } + else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; } if (Reg == x86_Any8Bit) { @@ -573,15 +641,15 @@ CX86Ops::x86Reg CRegInfo::Map_TempReg (CX86Ops::x86Reg Reg, int MipsReg, BOOL Lo return x86_Unknown; } } - } else if (x86Mapped(Reg) == GPR_Mapped) { - if (x86Protected(Reg)) + } else if (GetX86Mapped(Reg) == GPR_Mapped) { + if (GetX86Protected(Reg)) { WriteTrace(TraceError,"CRegInfo::Map_TempReg: Register is protected"); _Notify->BreakPoint(__FILE__,__LINE__); return x86_Unknown; } - x86Protected(Reg) = true; + SetX86Protected(Reg,true); x86Reg NewReg = FreeX86Reg(); for (count = 1; count < 32; count ++) { @@ -597,8 +665,8 @@ CX86Ops::x86Reg CRegInfo::Map_TempReg (CX86Ops::x86Reg Reg, int MipsReg, BOOL Lo break; } CPU_Message(" regcache: change allocation of %s from %s to %s",CRegName::GPR[count],x86_Name(Reg),x86_Name(NewReg)); - x86Mapped(NewReg) = GPR_Mapped; - x86MapOrder(NewReg) = x86MapOrder(Reg); + SetX86Mapped(NewReg,GPR_Mapped); + SetX86MapOrder(NewReg,GetX86MapOrder(Reg)); MipsRegMapLo(count) = NewReg; MoveX86RegToX86Reg(Reg,NewReg); if (MipsReg == count && LoadHiWord == FALSE) { MipsReg = -1; } @@ -612,8 +680,8 @@ CX86Ops::x86Reg CRegInfo::Map_TempReg (CX86Ops::x86Reg Reg, int MipsReg, BOOL Lo break; } CPU_Message(" regcache: change allocation of %s from %s to %s",CRegName::GPR_Hi[count],x86_Name(Reg),x86_Name(NewReg)); - x86Mapped(NewReg) = GPR_Mapped; - x86MapOrder(NewReg) = x86MapOrder(Reg); + SetX86Mapped(NewReg,GPR_Mapped); + SetX86MapOrder(NewReg,GetX86MapOrder(Reg)); MipsRegMapHi(count) = NewReg; MoveX86RegToX86Reg(Reg,NewReg); if (MipsReg == count && LoadHiWord == TRUE) { MipsReg = -1; } @@ -621,7 +689,7 @@ CX86Ops::x86Reg CRegInfo::Map_TempReg (CX86Ops::x86Reg Reg, int MipsReg, BOOL Lo } } } - else if (x86Mapped(Reg) == Stack_Mapped) + else if (GetX86Mapped(Reg) == Stack_Mapped) { UnMap_X86reg(Reg); } @@ -661,38 +729,40 @@ CX86Ops::x86Reg CRegInfo::Map_TempReg (CX86Ops::x86Reg Reg, int MipsReg, BOOL Lo } } } - x86Mapped(Reg) = Temp_Mapped; - x86Protected(Reg) = TRUE; - for (count = 0; count < 10; count ++) { - if (x86MapOrder((x86Reg)count) > 0) { - x86MapOrder((x86Reg)count) += 1; + SetX86Mapped(Reg,Temp_Mapped); + SetX86Protected(Reg,TRUE); + for (count = 0; count < 10; count ++) + { + int MapOrder = GetX86MapOrder((x86Reg)count); + if (MapOrder > 0) { + SetX86MapOrder((x86Reg)count,MapOrder + 1); } } - x86MapOrder(Reg) = 1; + SetX86MapOrder(Reg,1); return Reg; } void CRegInfo::ProtectGPR(DWORD Reg) { if (IsUnknown(Reg) || IsConst(Reg)) { return; } if (Is64Bit(Reg)) { - x86Protected(MipsRegMapHi(Reg)) = TRUE; + SetX86Protected(MipsRegMapHi(Reg),TRUE); } - x86Protected(MipsRegMapLo(Reg)) = TRUE; + SetX86Protected(MipsRegMapLo(Reg),TRUE); } void CRegInfo::UnProtectGPR(DWORD Reg) { if (IsUnknown(Reg) || IsConst(Reg)) { return; } if (Is64Bit(Reg)) { - x86Protected(MipsRegMapHi(Reg)) = false; + SetX86Protected(MipsRegMapHi(Reg),false); } - x86Protected(MipsRegMapLo(Reg)) = false; + SetX86Protected(MipsRegMapLo(Reg),false); } void CRegInfo::ResetX86Protection (void) { for (int count = 0; count < 10; count ++) { - x86Protected((x86Reg)count) = false; + SetX86Protected((x86Reg)count, false); } } @@ -798,7 +868,7 @@ void CRegInfo::UnMap_FPR (int Reg, int WriteBackValue ) DisplayError("UnMap_FPR\nUnknown format to load %d",x86fpu_State[StackTopPos()]); #endif } - x86Protected(TempReg) = FALSE; + SetX86Protected(TempReg,FALSE); FpuRoundingModel(RegPos) = RoundDefault; x86fpu_MappedTo[RegPos] = -1; x86fpu_State[RegPos] = FPU_Unknown; @@ -847,13 +917,14 @@ void CRegInfo::UnMap_GPR (DWORD Reg, bool WriteBackValue) } if (Is64Bit(Reg)) { CPU_Message(" regcache: unallocate %s from %s",x86_Name(MipsRegMapHi(Reg)),CRegName::GPR_Hi[Reg]); - x86Mapped(MipsRegMapHi(Reg)) = NotMapped; - x86Protected(MipsRegMapHi(Reg)) = FALSE; + SetX86Mapped(MipsRegMapHi(Reg),NotMapped); + SetX86Protected(MipsRegMapHi(Reg),FALSE); } CPU_Message(" regcache: unallocate %s from %s",x86_Name(MipsRegMapLo(Reg)),CRegName::GPR_Lo[Reg]); - x86Mapped(MipsRegMapLo(Reg)) = NotMapped; - x86Protected(MipsRegMapLo(Reg)) = FALSE; - if (!WriteBackValue) { + SetX86Mapped(MipsRegMapLo(Reg),NotMapped); + SetX86Protected(MipsRegMapLo(Reg),FALSE); + if (!WriteBackValue) + { MipsRegState(Reg) = STATE_UNKNOWN; return; } @@ -875,22 +946,22 @@ CX86Ops::x86Reg CRegInfo::UnMap_TempReg ( void ) { CX86Ops::x86Reg Reg = x86_Unknown; - if (x86Mapped(x86_EAX) == Temp_Mapped && !x86Protected(x86_EAX)) { Reg = x86_EAX; } - else if (x86Mapped(x86_EBX) == Temp_Mapped && !x86Protected(x86_EBX)) { Reg = x86_EBX; } - else if (x86Mapped(x86_ECX) == Temp_Mapped && !x86Protected(x86_ECX)) { Reg = x86_ECX; } - else if (x86Mapped(x86_EDX) == Temp_Mapped && !x86Protected(x86_EDX)) { Reg = x86_EDX; } - else if (x86Mapped(x86_ESI) == Temp_Mapped && !x86Protected(x86_ESI)) { Reg = x86_ESI; } - else if (x86Mapped(x86_EDI) == Temp_Mapped && !x86Protected(x86_EDI)) { Reg = x86_EDI; } - else if (x86Mapped(x86_EBP) == Temp_Mapped && !x86Protected(x86_EBP)) { Reg = x86_EBP; } - else if (x86Mapped(x86_ESP) == Temp_Mapped && !x86Protected(x86_ESP)) { Reg = x86_ESP; } + if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; } + else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; } + else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; } + else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; } + else if (GetX86Mapped(x86_ESI) == Temp_Mapped && !GetX86Protected(x86_ESI)) { Reg = x86_ESI; } + else if (GetX86Mapped(x86_EDI) == Temp_Mapped && !GetX86Protected(x86_EDI)) { Reg = x86_EDI; } + else if (GetX86Mapped(x86_EBP) == Temp_Mapped && !GetX86Protected(x86_EBP)) { Reg = x86_EBP; } + else if (GetX86Mapped(x86_ESP) == Temp_Mapped && !GetX86Protected(x86_ESP)) { Reg = x86_ESP; } if (Reg != x86_Unknown) { - if (x86Mapped(Reg) == Temp_Mapped) + if (GetX86Mapped(Reg) == Temp_Mapped) { CPU_Message(" regcache: unallocate %s from temp storage",x86_Name(Reg)); } - x86Mapped(Reg) = NotMapped; + SetX86Mapped(Reg,NotMapped); } return Reg; } @@ -899,11 +970,11 @@ bool CRegInfo::UnMap_X86reg ( CX86Ops::x86Reg Reg ) { int count; - if (x86Mapped(Reg) == NotMapped && x86Protected(Reg) == FALSE) { return TRUE; } - if (x86Mapped(Reg) == CRegInfo::Temp_Mapped) { - if (x86Protected(Reg) == FALSE) { + if (GetX86Mapped(Reg) == NotMapped && GetX86Protected(Reg) == FALSE) { return TRUE; } + if (GetX86Mapped(Reg) == CRegInfo::Temp_Mapped) { + if (GetX86Protected(Reg) == FALSE) { CPU_Message(" regcache: unallocate %s from temp storage",x86_Name(Reg)); - x86Mapped(Reg) = NotMapped; + SetX86Mapped(Reg,NotMapped); return TRUE; } return FALSE; @@ -916,7 +987,7 @@ bool CRegInfo::UnMap_X86reg ( CX86Ops::x86Reg Reg ) } if (Is64Bit(count) && MipsRegMapHi(count) == Reg) { - if (x86Protected(Reg) == FALSE) + if (GetX86Protected(Reg) == FALSE) { UnMap_GPR(count,TRUE); return TRUE; @@ -925,7 +996,7 @@ bool CRegInfo::UnMap_X86reg ( CX86Ops::x86Reg Reg ) } if (MipsRegMapLo(count) == Reg) { - if (x86Protected(Reg) == FALSE) + if (GetX86Protected(Reg) == FALSE) { UnMap_GPR(count,TRUE); return TRUE; @@ -933,14 +1004,11 @@ bool CRegInfo::UnMap_X86reg ( CX86Ops::x86Reg Reg ) break; } } - if (x86Mapped(Reg) == CRegInfo::Stack_Mapped) { - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix + if (GetX86Mapped(Reg) == CRegInfo::Stack_Mapped) { CPU_Message(" regcache: unallocate %s from Memory Stack",x86_Name(Reg)); - MoveX86regToVariable(Reg,g_MemoryStack,"MemoryStack"); - x86Mapped(Reg) = NotMapped; + MoveX86regToVariable(Reg,&(_Recompiler->MemoryStackPos()),"MemoryStack"); + SetX86Mapped(Reg,NotMapped); return TRUE; -#endif } return FALSE; } @@ -956,7 +1024,7 @@ void CRegInfo::WriteBackRegisters (void) BOOL bEaxGprLo = FALSE; BOOL bEbxGprHi = FALSE; - for (count = 0; count < 10; count ++) { x86Protected((CX86Ops::x86Reg)count) = FALSE; } + for (count = 0; count < 10; count ++) { SetX86Protected((CX86Ops::x86Reg)count,FALSE); } for (count = 0; count < 10; count ++) { UnMap_X86reg ((CX86Ops::x86Reg)count); } /*************************************/ diff --git a/Source/Project64/N64 System/Recompiler/Reg Info.h b/Source/Project64/N64 System/Recompiler/Reg Info.h index 435389dcf..05a71459a 100644 --- a/Source/Project64/N64 System/Recompiler/Reg Info.h +++ b/Source/Project64/N64 System/Recompiler/Reg Info.h @@ -63,6 +63,7 @@ public: x86Reg Free8BitX86Reg ( void ); void Map_GPR_32bit ( int MipsReg, BOOL SignValue, int MipsRegToLoad ); void Map_GPR_64bit ( int MipsReg, int MipsRegToLoad ); + x86Reg Map_MemoryStack ( x86Reg Reg, bool bMapRegister ); x86Reg Map_TempReg ( x86Reg Reg, int MipsReg, BOOL LoadHiWord ); void ProtectGPR ( DWORD Reg ); void UnProtectGPR ( DWORD Reg ); @@ -109,11 +110,16 @@ public: inline CX86Ops::x86Reg & MipsRegMapHi ( int Reg ) { return RegMapHi[Reg]; } inline bool & X86Protected ( x86Reg Reg ) { return x86reg_Protected[Reg]; } - inline DWORD & x86MapOrder( x86Reg Reg ) { return x86reg_MapOrder[Reg]; } - inline bool & x86Protected( x86Reg Reg ) { return x86reg_Protected[Reg]; } - inline REG_MAPPED & x86Mapped(x86Reg Reg) { return x86reg_MappedTo[Reg]; } + inline DWORD GetX86MapOrder ( x86Reg Reg ) const { return x86reg_MapOrder[Reg]; } + inline bool GetX86Protected ( x86Reg Reg ) const { return x86reg_Protected[Reg]; } + inline REG_MAPPED GetX86Mapped ( x86Reg Reg ) const { return x86reg_MappedTo[Reg]; } + + inline DWORD GetBlockCycleCount ( void ) const { return m_CycleCount; } + + inline void SetX86MapOrder ( x86Reg Reg, DWORD Order ) { x86reg_MapOrder[Reg] = Order; } + inline void SetX86Protected ( x86Reg Reg, bool Protected ) { x86reg_Protected[Reg] = Protected; } + inline void SetX86Mapped ( x86Reg Reg, REG_MAPPED Mapping ) { x86reg_MappedTo[Reg] = Mapping; } - inline DWORD GetBlockCycleCount ( void ) const { return m_CycleCount; } inline void SetBlockCycleCount ( DWORD CyleCount ) { m_CycleCount = CyleCount; } inline int & StackTopPos ( void ) { return Stack_TopPos; } @@ -121,7 +127,9 @@ public: inline FPU_STATE & FpuState(int Reg) { return x86fpu_State[Reg]; } inline FPU_ROUND & FpuRoundingModel(int Reg) { return x86fpu_RoundingModel[Reg]; } inline bool & FpuBeenUsed (void ) { return Fpu_Used; } - inline FPU_ROUND & CurrentRoundingModel ( void ) { return RoundingModel; } + + inline FPU_ROUND GetRoundingModel ( void ) const { return m_RoundingModel; } + inline void SetRoundingModel ( FPU_ROUND RoundingModel ) { m_RoundingModel = RoundingModel; } private: x86Reg UnMap_8BitTempReg ( void ); @@ -146,7 +154,7 @@ private: FPU_ROUND x86fpu_RoundingModel[8]; bool Fpu_Used; - FPU_ROUND RoundingModel; + FPU_ROUND m_RoundingModel; bool compare(const CRegInfo& right) const; const char * RoundingModelName ( FPU_ROUND RoundType ); diff --git a/Source/Project64/N64 System/Recompiler/Section Info.cpp b/Source/Project64/N64 System/Recompiler/Section Info.cpp index 7cff4fe76..8fd2e09e7 100644 --- a/Source/Project64/N64 System/Recompiler/Section Info.cpp +++ b/Source/Project64/N64 System/Recompiler/Section Info.cpp @@ -12,16 +12,15 @@ CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos, bool bDelaySlot) : AnalyseBlock(); } -void CCodeBlock::AnalyseBlock ( void ) +bool CCodeBlock::AnalyseBlock ( void ) { - /*if (bLinkBlocks()) + if (bLinkBlocks()) { - CCodeSection * Section = &ParentSection; - if (!CreateSectionLinkage (Section)) { return false; } - DetermineLoop(Section,CCodeSection::GetNewTestValue(),CCodeSection::GetNewTestValue(), Section->SectionID); - while (FixConstants(Section,CCodeSection::GetNewTestValue())) {} + if (!m_EnterSection.CreateSectionLinkage ()) { return false; } + m_EnterSection.DetermineLoop(NextTest(),NextTest(), m_EnterSection.m_SectionID); + while (m_EnterSection.FixConstants(NextTest())) {} } - return true;*/ + return true; } bool CCodeBlock::Compile() @@ -224,70 +223,6 @@ DWORD CCodeSection::GetNewTestValue(void) return LastTest; } -void CCodeSection::TestRegConstantStates( CRegInfo & Base, CRegInfo & Reg ) -{ - for (int count = 0; count < 32; count++) { - if (Reg.MipsRegState(count) != Base.MipsRegState(count)) { - Reg.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; - } - if (Reg.IsConst(count)) - { - if (Reg.Is32Bit(count)) - { - if (Reg.MipsRegLo(count) != Base.MipsRegLo(count)) { - Reg.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; - } - } else { - if (Reg.MipsReg(count) != Base.MipsReg(count)) { - Reg.MipsRegState(count) = CRegInfo::STATE_UNKNOWN; - } - } - - } - } -} - -void CCodeSection::AddParent(CCodeSection * Parent ) -{ - if (this == NULL) { return; } - if (Parent == NULL) - { - RegStart.Initilize(); - RegWorking = RegStart; - return; - } - - // check to see if we already have the parent in the list - for (SECTION_LIST::iterator iter = ParentSection.begin(); iter != ParentSection.end(); iter++) - { - if (*iter == Parent) - { - return; - } - } - ParentSection.push_back(Parent); - - if (ParentSection.size() == 1) - { - if (Parent->ContinueSection == this) { - RegStart = Parent->Cont.RegSet; - } else if (Parent->JumpSection == this) { - RegStart = Parent->Jump.RegSet; - } else { - _Notify->DisplayError("How are these sections joined?????"); - } - RegWorking = RegStart; - } else { - if (Parent->ContinueSection == this) { - TestRegConstantStates(Parent->Cont.RegSet,RegStart); - } - if (Parent->JumpSection == this) { - TestRegConstantStates(Parent->Jump.RegSet,RegStart); - } - RegWorking = RegStart; - } -} - void CRegInfo::Initilize ( void ) { int count; @@ -358,7 +293,7 @@ bool CRegInfo::compare(const CRegInfo& right) const if (x86fpu_RoundingModel[count] != right.x86fpu_RoundingModel[count]) { return false; } } if (Fpu_Used != right.Fpu_Used) { return false; } - if (RoundingModel != right.RoundingModel) { return false; } + if (GetRoundingModel() != right.GetRoundingModel()) { return false; } return true; } diff --git a/Source/Project64/N64 System/Recompiler/Section Info.h b/Source/Project64/N64 System/Recompiler/Section Info.h index 0bb97bf2e..0652acb98 100644 --- a/Source/Project64/N64 System/Recompiler/Section Info.h +++ b/Source/Project64/N64 System/Recompiler/Section Info.h @@ -1,5 +1,4 @@ class CCodeSection; -typedef std::list SECTION_LIST; class CCodeBlock; diff --git a/Source/Project64/N64 System/Speed Limitor Class.cpp b/Source/Project64/N64 System/Speed Limitor Class.cpp index 675eae469..706b33282 100644 --- a/Source/Project64/N64 System/Speed Limitor Class.cpp +++ b/Source/Project64/N64 System/Speed Limitor Class.cpp @@ -72,6 +72,10 @@ void CSpeedLimitor::IncreaeSpeed ( int Percent ) void CSpeedLimitor::DecreaeSpeed ( int Percent ) { - m_Speed -= m_BaseSpeed * ((float)Percent / 100); - FixSpeedRatio(); + ULONG Unit = m_BaseSpeed * ((float)Percent / 100); + if (m_Speed > Unit) + { + m_Speed -= Unit; + FixSpeedRatio(); + } } \ No newline at end of file diff --git a/Source/Project64/Settings.h b/Source/Project64/Settings.h index 9ae624dfb..efad34e9f 100644 --- a/Source/Project64/Settings.h +++ b/Source/Project64/Settings.h @@ -45,7 +45,7 @@ enum SettingID { Rdb_CounterFactor, Rdb_UseTlb, Rdb_DelaySi, - Rdb_SPHack, + Rdb_FastSP, Rdb_Status, Rdb_NotesCore, Rdb_NotesPlugin, @@ -99,7 +99,7 @@ enum SettingID { Game_CounterFactor, Game_UseTlb, Game_DelaySI, - Game_SPHack, + Game_FastSP, Game_FuncLookupMode, Game_RegCache, Game_BlockLinking, diff --git a/Source/Project64/Settings/N64System Settings.cpp b/Source/Project64/Settings/N64System Settings.cpp index 38e57e8f0..537c5b19c 100644 --- a/Source/Project64/Settings/N64System Settings.cpp +++ b/Source/Project64/Settings/N64System Settings.cpp @@ -10,7 +10,7 @@ bool CN64SystemSettings::m_bShowDListAListCount; bool CN64SystemSettings::m_bFixedAudio; bool CN64SystemSettings::m_bSyncToAudio; bool CN64SystemSettings::m_bDisplayFrameRate; -bool CN64SystemSettings::m_SPHack; +bool CN64SystemSettings::m_bFastSP; DWORD CN64SystemSettings::m_ViRefreshRate; @@ -30,7 +30,7 @@ CN64SystemSettings::CN64SystemSettings() _Settings->RegisterChangeCB(Game_FixedAudio,NULL,RefreshSettings); _Settings->RegisterChangeCB(Game_SyncViaAudio,NULL,RefreshSettings); - _Settings->RegisterChangeCB(Game_SPHack,NULL,RefreshSettings); + _Settings->RegisterChangeCB(Game_FastSP,NULL,RefreshSettings); _Settings->RegisterChangeCB(Game_ViRefreshRate,NULL,RefreshSettings); RefreshSettings(NULL); } @@ -52,7 +52,7 @@ CN64SystemSettings::~CN64SystemSettings() _Settings->UnregisterChangeCB(Game_FixedAudio,NULL,RefreshSettings); _Settings->UnregisterChangeCB(Game_SyncViaAudio,NULL,RefreshSettings); - _Settings->UnregisterChangeCB(Game_SPHack,NULL,RefreshSettings); + _Settings->UnregisterChangeCB(Game_FastSP,NULL,RefreshSettings); _Settings->UnregisterChangeCB(Game_ViRefreshRate,NULL,RefreshSettings); } } @@ -69,6 +69,6 @@ void CN64SystemSettings::RefreshSettings(void *) m_bFixedAudio = _Settings->LoadBool(Game_FixedAudio); m_bSyncToAudio = m_bFixedAudio ? _Settings->LoadBool(Game_SyncViaAudio) : false; - m_SPHack = _Settings->LoadBool(Game_SPHack); + m_bFastSP = _Settings->LoadBool(Game_FastSP); m_ViRefreshRate = _Settings->LoadDword(Game_ViRefreshRate); } diff --git a/Source/Project64/Settings/N64System Settings.h b/Source/Project64/Settings/N64System Settings.h index 645f44771..5ce0a914e 100644 --- a/Source/Project64/Settings/N64System Settings.h +++ b/Source/Project64/Settings/N64System Settings.h @@ -14,7 +14,7 @@ protected: inline bool bLimitFPS ( void ) const { return m_bLimitFPS; } inline bool bFixedAudio ( void ) const { return m_bFixedAudio; } inline bool bSyncToAudio ( void ) const { return m_bSyncToAudio; } - inline bool bSPHack ( void ) const { return m_SPHack; } + inline bool bFastSP ( void ) const { return m_bFastSP; } inline DWORD ViRefreshRate ( void ) const { return m_ViRefreshRate; } private: @@ -28,7 +28,7 @@ private: static bool m_bFixedAudio; static bool m_bSyncToAudio; static bool m_bDisplayFrameRate; - static bool m_SPHack; + static bool m_bFastSP; static DWORD m_ViRefreshRate; static int m_RefCount; diff --git a/Source/Project64/Settings/Recompiler Settings.cpp b/Source/Project64/Settings/Recompiler Settings.cpp index 9ae088274..ddacb68e0 100644 --- a/Source/Project64/Settings/Recompiler Settings.cpp +++ b/Source/Project64/Settings/Recompiler Settings.cpp @@ -8,6 +8,7 @@ bool CRecompilerSettings::m_bSMM_PIDMA; bool CRecompilerSettings::m_bSMM_TLB; bool CRecompilerSettings::m_bProfiling; bool CRecompilerSettings::m_bRomInMemory; +bool CRecompilerSettings::m_bFastSP; bool CRecompilerSettings::m_RegCaching; bool CRecompilerSettings::m_bLinkBlocks; DWORD CRecompilerSettings::m_RdramSize; @@ -29,6 +30,7 @@ CRecompilerSettings::CRecompilerSettings() _Settings->RegisterChangeCB(Debugger_ShowRecompMemSize,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); _Settings->RegisterChangeCB(Debugger_ProfileCode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); _Settings->RegisterChangeCB(Game_LoadRomToMemory,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->RegisterChangeCB(Game_FastSP,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); RefreshSettings(); } @@ -48,6 +50,7 @@ CRecompilerSettings::~CRecompilerSettings() _Settings->UnregisterChangeCB(Debugger_ShowRecompMemSize,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); _Settings->UnregisterChangeCB(Debugger_ProfileCode,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); _Settings->UnregisterChangeCB(Game_LoadRomToMemory,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); + _Settings->UnregisterChangeCB(Game_FastSP,this,(CSettings::SettingChangedFunc)StaticRefreshSettings); } void CRecompilerSettings::RefreshSettings() @@ -60,6 +63,7 @@ void CRecompilerSettings::RefreshSettings() m_bShowRecompMemSize = _Settings->LoadBool(Debugger_ShowRecompMemSize); m_bProfiling = _Settings->LoadBool(Debugger_ProfileCode); m_bRomInMemory = _Settings->LoadBool(Game_LoadRomToMemory); + m_bFastSP = _Settings->LoadBool(Game_FastSP); m_RegCaching = _Settings->LoadBool(Game_RegCache); m_bLinkBlocks = _Settings->LoadBool(Game_BlockLinking); diff --git a/Source/Project64/Settings/Recompiler Settings.h b/Source/Project64/Settings/Recompiler Settings.h index 1e343fec7..c96a90452 100644 --- a/Source/Project64/Settings/Recompiler Settings.h +++ b/Source/Project64/Settings/Recompiler Settings.h @@ -19,6 +19,7 @@ class CRecompilerSettings static bool m_bSMM_TLB; static bool m_bProfiling; static bool m_bRomInMemory; + static bool m_bFastSP; static bool m_RegCaching; static bool m_bLinkBlocks; @@ -30,18 +31,19 @@ public: CRecompilerSettings(); virtual ~CRecompilerSettings(); - inline bool bShowRecompMemSize ( void ) const { return m_bShowRecompMemSize; } + static bool bShowRecompMemSize ( void ) { return m_bShowRecompMemSize; } - inline bool bSMM_StoreInstruc ( void ) const { return m_bSMM_StoreInstruc; } - inline bool bSMM_Protect ( void ) const { return m_bSMM_Protect; } - inline bool bSMM_ValidFunc ( void ) const { return m_bSMM_ValidFunc; } - inline bool bSMM_PIDMA ( void ) const { return m_bSMM_PIDMA; } - inline bool bSMM_TLB ( void ) const { return m_bSMM_TLB; } - inline bool bProfiling ( void ) const { return m_bProfiling; } - inline bool bRomInMemory ( void ) const { return m_bRomInMemory; } - inline bool bRegCaching ( void ) const { return m_RegCaching; } - inline bool bLinkBlocks ( void ) const { return m_bLinkBlocks; } - inline DWORD RdramSize ( void ) const { return m_RdramSize; } - inline DWORD CountPerOp ( void ) const { return m_CountPerOp; } - inline FUNC_LOOKUP_METHOD LookUpMode ( void ) const { return (FUNC_LOOKUP_METHOD)m_LookUpMode; } + static bool bSMM_StoreInstruc ( void ) { return m_bSMM_StoreInstruc; } + static bool bSMM_Protect ( void ) { return m_bSMM_Protect; } + static bool bSMM_ValidFunc ( void ) { return m_bSMM_ValidFunc; } + static bool bSMM_PIDMA ( void ) { return m_bSMM_PIDMA; } + static bool bSMM_TLB ( void ) { return m_bSMM_TLB; } + static bool bProfiling ( void ) { return m_bProfiling; } + static bool bRomInMemory ( void ) { return m_bRomInMemory; } + static bool bRegCaching ( void ) { return m_RegCaching; } + static bool bLinkBlocks ( void ) { return m_bLinkBlocks; } + static bool bFastSP ( void ) { return m_bFastSP; } + static DWORD RdramSize ( void ) { return m_RdramSize; } + static DWORD CountPerOp ( void ) { return m_CountPerOp; } + static FUNC_LOOKUP_METHOD LookUpMode ( void ) { return (FUNC_LOOKUP_METHOD)m_LookUpMode; } }; \ No newline at end of file diff --git a/Source/Project64/Settings/Settings Class.cpp b/Source/Project64/Settings/Settings Class.cpp index 9c9a354fa..3633761f8 100644 --- a/Source/Project64/Settings/Settings Class.cpp +++ b/Source/Project64/Settings/Settings Class.cpp @@ -102,7 +102,7 @@ void CSettings::AddHowToHandleSetting () AddHandler(Rdb_CounterFactor, new CSettingTypeRomDatabase("Counter Factor",2)); AddHandler(Rdb_UseTlb, new CSettingTypeRDBYesNo("Use TLB",true)); AddHandler(Rdb_DelaySi, new CSettingTypeRDBYesNo("Delay SI",false)); - AddHandler(Rdb_SPHack, new CSettingTypeRDBYesNo("SP Hack",false)); + AddHandler(Rdb_FastSP, new CSettingTypeRDBYesNo("Fast SP",true)); AddHandler(Rdb_Status, new CSettingTypeRomDatabase("Status","Unknown")); AddHandler(Rdb_NotesCore, new CSettingTypeRomDatabase("Core Note","")); AddHandler(Rdb_NotesPlugin, new CSettingTypeRomDatabase("Plugin Note","")); @@ -148,7 +148,7 @@ void CSettings::AddHowToHandleSetting () AddHandler(Game_UseTlb, new CSettingTypeGame("Use TLB",Rdb_UseTlb)); AddHandler(Game_DelaySI, new CSettingTypeGame("Delay SI",Rdb_DelaySi)); AddHandler(Game_RspAudioSignal, new CSettingTypeGame("Audio Signal",Rdb_RspAudioSignal)); - AddHandler(Game_SPHack, new CSettingTypeGame("SP Hack",Rdb_SPHack)); + AddHandler(Game_FastSP, new CSettingTypeGame("SP Hack",Rdb_FastSP)); AddHandler(Game_CurrentSaveState, new CSettingTypeTempNumber(0)); AddHandler(Game_SyncViaAudio, new CSettingTypeGame("Sync Audio",Rdb_SyncViaAudio)); AddHandler(Game_UseHleGfx, new CSettingTypeGame("HLE GFX",Rdb_UseHleGfx)); diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.cpp b/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.cpp index 287726892..098366003 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.cpp +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.cpp @@ -19,7 +19,7 @@ CGameRecompilePage::CGameRecompilePage (HWND hParent, const RECT & rcDispay ) AddModCheckBox(GetDlgItem(IDC_SMM_TLB),Game_SMM_TLB); AddModCheckBox(GetDlgItem(IDC_SMM_PROTECT),Game_SMM_Protect); AddModCheckBox(GetDlgItem(IDC_SMM_STORE),Game_SMM_StoreInstruc); - AddModCheckBox(GetDlgItem(IDC_ROM_SPHACK),Game_SPHack); + AddModCheckBox(GetDlgItem(IDC_ROM_FASTSP),Game_FastSP); CModifiedComboBox * ComboBox; ComboBox = AddModComboBox(GetDlgItem(IDC_CPU_TYPE),Game_CpuType); diff --git a/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.h b/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.h index 09247c568..4cbb57956 100644 --- a/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.h +++ b/Source/Project64/User Interface/Settings/Settings Page - Game - Recompiler.h @@ -9,13 +9,13 @@ class CGameRecompilePage : COMMAND_HANDLER_EX(IDC_CPU_TYPE,LBN_SELCHANGE,ComboBoxChanged) COMMAND_HANDLER_EX(IDC_FUNCFIND,LBN_SELCHANGE,ComboBoxChanged) COMMAND_ID_HANDLER_EX(IDC_ROM_REGCACHE,CheckBoxChanged) + COMMAND_ID_HANDLER_EX(IDC_ROM_FASTSP,CheckBoxChanged) COMMAND_ID_HANDLER_EX(IDC_BLOCK_LINKING,CheckBoxChanged) COMMAND_ID_HANDLER_EX(IDC_SMM_CACHE,CheckBoxChanged) COMMAND_ID_HANDLER_EX(IDC_SMM_DMA,CheckBoxChanged) COMMAND_ID_HANDLER_EX(IDC_SMM_VALIDATE,CheckBoxChanged) COMMAND_ID_HANDLER_EX(IDC_SMM_TLB,CheckBoxChanged) COMMAND_ID_HANDLER_EX(IDC_SMM_PROTECT,CheckBoxChanged) - COMMAND_ID_HANDLER_EX(IDC_ROM_SPHACK,CheckBoxChanged) COMMAND_ID_HANDLER_EX(IDC_SMM_STORE,CheckBoxChanged) END_MSG_MAP() diff --git a/Source/Project64/User Interface/UI Resources.aps b/Source/Project64/User Interface/UI Resources.aps index e17f72130ea9f685e8bb89a813efa6275dfc391d..ece29836739dade87637e4e8146bfe424f2ecfe1 100644 GIT binary patch delta 58 zcmeCVE!1;csG)_ig{g&k3roN}PHhHb26hHU2JP*U^H_Kp8I7l>&u6J*He@i^{&+qM NH&9^v`voj>c>n>o5hnlu delta 58 zcmeCVE!1;csG)_ig{g&k3roN}PAvvw26hHU2CeOp^H_Kp8I7i=&u6J*HefK>{&+qM NH&9^v`voj>c>n=>5heft diff --git a/Source/Project64/User Interface/UI Resources.rc b/Source/Project64/User Interface/UI Resources.rc index 9d2aae214..4647a1fff 100644 --- a/Source/Project64/User Interface/UI Resources.rc +++ b/Source/Project64/User Interface/UI Resources.rc @@ -740,7 +740,7 @@ BEGIN 208,1 CONTROL "Advanced Block Linking",IDC_BLOCK_LINKING,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,113,49,95,11 - CONTROL "SP Hack",IDC_ROM_SPHACK,"Button",BS_AUTOCHECKBOX | + CONTROL "Fast SP",IDC_ROM_FASTSP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,62,91,11 CONTROL "Store Instruction",IDC_SMM_STORE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,116,91,89,8 @@ -1087,8 +1087,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,7,51,42 - PRODUCTVERSION 1,7,51,42 + FILEVERSION 1,7,51,43 + PRODUCTVERSION 1,7,51,43 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -1106,14 +1106,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", " \0" VALUE "FileDescription", "Project64\0" - VALUE "FileVersion", "1, 7, 51, 42\0" + VALUE "FileVersion", "1, 7, 51, 43\0" VALUE "InternalName", "Project64\0" - VALUE "LegalCopyright", "Copyright © 2004\0" + VALUE "LegalCopyright", "Copyright © 2010\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "Project64.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", " Project64\0" - VALUE "ProductVersion", "1, 7, 51, 42\0" + VALUE "ProductVersion", "1, 7, 51, 43\0" VALUE "SpecialBuild", "\0" END END diff --git a/Source/Project64/User Interface/resource.h b/Source/Project64/User Interface/resource.h index 14c3aad52..c870a24f1 100644 --- a/Source/Project64/User Interface/resource.h +++ b/Source/Project64/User Interface/resource.h @@ -240,7 +240,7 @@ #define IDC_ROM_REGCACHE 1099 #define IDC_CONT_NAME 1100 #define IDC_DIR_FRAME1 1101 -#define IDC_ROM_SPHACK 1101 +#define IDC_ROM_FASTSP 1101 #define IDC_AUDIO_SIGNAL 1102 #define IDC_DIR_TEXTURE_FRAME 1102 #define IDC_DIR_FRAME3 1103