From 4a3073af6d4cc4945853926c21391cbb9c9765aa Mon Sep 17 00:00:00 2001 From: zilmar Date: Mon, 22 Oct 2012 19:02:53 +1100 Subject: [PATCH] More bug fixing related to changes ABL --- .../N64 System/Mips/Memory Virtual Mem.cpp | 39 +++- .../N64 System/Recompiler/Code Block.cpp | 53 +++-- .../N64 System/Recompiler/Code Section.cpp | 22 +- .../N64 System/Recompiler/Loop Analysis.cpp | 221 +++++------------- .../N64 System/Recompiler/Recompiler Ops.cpp | 108 +++++---- 5 files changed, 208 insertions(+), 235 deletions(-) diff --git a/Source/Project64/N64 System/Mips/Memory Virtual Mem.cpp b/Source/Project64/N64 System/Mips/Memory Virtual Mem.cpp index 407b19e19..554c363ad 100644 --- a/Source/Project64/N64 System/Mips/Memory Virtual Mem.cpp +++ b/Source/Project64/N64 System/Mips/Memory Virtual Mem.cpp @@ -400,9 +400,16 @@ void CMipsMemoryVM::Compile_LW (x86Reg Reg, DWORD VAddr ) { } break; case 0x04100000: - if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { _Notify->DisplayError("Compile_LW\nFailed to translate address: %X",VAddr); } - sprintf(VarName,"m_RDRAM + %X",PAddr); - MoveVariableToX86reg(PAddr + m_RDRAM,VarName,Reg); + { + static DWORD TempValue = 0; + BeforeCallDirect(m_RegWorkingSet); + PushImm32("TempValue",(DWORD)&TempValue); + PushImm32(PAddr); + MoveConstToX86reg((ULONG)((CMipsMemoryVM *)this),x86_ECX); + Call_Direct(AddressOf(&CMipsMemoryVM::LW_NonMemory),"CMipsMemoryVM::LW_NonMemory"); + AfterCallDirect(m_RegWorkingSet); + MoveVariableToX86reg(&TempValue,"TempValue",Reg); + } break; case 0x04300000: switch (PAddr) { @@ -1057,10 +1064,19 @@ void CMipsMemoryVM::Compile_SW_Register (x86Reg Reg, DWORD VAddr ) } break; case 0x04100000: - CPU_Message(" Should be moving %s in to %X ?!?",x86_Name(Reg),VAddr); - sprintf(VarName,"m_RDRAM + %X",PAddr); - MoveX86regToVariable(Reg,PAddr + m_RDRAM,VarName); - if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { _Notify->DisplayError("Compile_SW_Register\ntrying to store at %X?",VAddr); } + if (PAddr == 0x0410000C) + { + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount()-CountPerOp()); + UpdateCounters(m_RegWorkingSet,false,true); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount()+CountPerOp()); + } + BeforeCallDirect(m_RegWorkingSet); + Push(Reg); + PushImm32(PAddr); + MoveConstToX86reg((ULONG)((CMipsMemoryVM *)this),x86_ECX); + Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory),"CMipsMemoryVM::SW_NonMemory"); + AfterCallDirect(m_RegWorkingSet); + break; case 0x04300000: switch (PAddr) { case 0x04300000: @@ -1630,7 +1646,14 @@ int CMipsMemoryVM::LB_NonMemory ( DWORD /*PAddr*/, DWORD * Value, BOOL /*SignExt // return TRUE; } -int CMipsMemoryVM::LH_NonMemory ( DWORD /*PAddr*/, DWORD * Value, int/* SignExtend*/ ) { +int CMipsMemoryVM::LH_NonMemory ( DWORD PAddr, DWORD * Value, int/* SignExtend*/ ) +{ + if (PAddr < 0x800000) + { + * Value = 0; + return true; + } + _Notify->BreakPoint(__FILE__,__LINE__); // switch (PAddr & 0xFFF00000) { // default: diff --git a/Source/Project64/N64 System/Recompiler/Code Block.cpp b/Source/Project64/N64 System/Recompiler/Code Block.cpp index 11bff39c5..71ef7ea58 100644 --- a/Source/Project64/N64 System/Recompiler/Code Block.cpp +++ b/Source/Project64/N64 System/Recompiler/Code Block.cpp @@ -88,7 +88,7 @@ bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSe if (Section == NULL) { - Section = new CCodeSection(this,TargetPC,m_Sections.size() + 1,LinkAllowed); + Section = new CCodeSection(this,TargetPC,m_Sections.size(),LinkAllowed); if (Section == NULL) { _Notify->BreakPoint(__FILE__,__LINE__); @@ -100,7 +100,7 @@ bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSe m_SectionMap.insert(SectionMap::value_type(TargetPC,Section)); } Section->AddParent(CurrentSection); - if (TargetPC < CurrentPC && TargetPC != m_VAddrEnter) + if (TargetPC <= CurrentPC && TargetPC != m_VAddrEnter) { CCodeSection * SplitSection = NULL; for (SectionMap::const_iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++) @@ -121,6 +121,7 @@ bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSe } if (SplitSection->m_EndPC >= TargetPC) { + CPU_Message(__FUNCTION__ ": Split Section: %d with section: %d",SplitSection->m_SectionID, Section->m_SectionID); CCodeSection * BaseSection = Section; BaseSection->m_EndPC = SplitSection->m_EndPC; BaseSection->SetJumpAddress(SplitSection->m_Jump.JumpPC, SplitSection->m_Jump.TargetPC,SplitSection->m_Jump.PermLoop); @@ -395,6 +396,10 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin { case R4300i_REGIMM_BLTZ: TargetPC = PC + ((short)Command.offset << 2) + 4; + if (TargetPC == PC + 8) + { + _Notify->BreakPoint(__FILE__,__LINE__); + } if (TargetPC == PC) { _Notify->BreakPoint(__FILE__,__LINE__); @@ -405,6 +410,10 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin case R4300i_REGIMM_BGEZ: case R4300i_REGIMM_BGEZAL: TargetPC = PC + ((short)Command.offset << 2) + 4; + if (TargetPC == PC + 8) + { + _Notify->BreakPoint(__FILE__,__LINE__); + } IncludeDelaySlot = true; if (Command.rs != 0) { @@ -455,24 +464,37 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin break; case R4300i_BEQ: TargetPC = PC + ((short)Command.offset << 2) + 4; - if (Command.rs != 0 || Command.rt != 0) + if (TargetPC == PC + 8) { - ContinuePC = PC + 8; - } else if (TargetPC == PC) { - PermLoop = true; + TargetPC = (DWORD)-1; + } else { + if (Command.rs != 0 || Command.rt != 0) + { + ContinuePC = PC + 8; + } else if (TargetPC == PC) { + PermLoop = true; + } + IncludeDelaySlot = true; } - IncludeDelaySlot = true; break; case R4300i_BNE: case R4300i_BLEZ: case R4300i_BGTZ: TargetPC = PC + ((short)Command.offset << 2) + 4; - if (TargetPC == PC) + if (TargetPC == PC + 8) { - _Notify->BreakPoint(__FILE__,__LINE__); + TargetPC = (DWORD)-1; + } else { + if (TargetPC == PC) + { + if (!DelaySlotEffectsCompare(PC,Command.rs,Command.rt)) + { + PermLoop = true; + } + } + ContinuePC = PC + 8; + IncludeDelaySlot = true; } - ContinuePC = PC + 8; - IncludeDelaySlot = true; break; case R4300i_CP0: switch (Command.rs) @@ -502,14 +524,19 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin break; case R4300i_CP1: switch (Command.fmt) { - case R4300i_COP1_MF: case R4300i_COP1_CF: case R4300i_COP1_MT: case R4300i_COP1_CT: - case R4300i_COP1_S: case R4300i_COP1_D: case R4300i_COP1_W: case R4300i_COP1_L: + case R4300i_COP1_MF: case R4300i_COP1_DMF: case R4300i_COP1_CF: case R4300i_COP1_MT: + case R4300i_COP1_DMT: case R4300i_COP1_CT: case R4300i_COP1_S: case R4300i_COP1_D: + case R4300i_COP1_W: case R4300i_COP1_L: break; case R4300i_COP1_BC: switch (Command.ft) { case R4300i_COP1_BC_BCF: case R4300i_COP1_BC_BCT: TargetPC = PC + ((short)Command.offset << 2) + 4; + if (TargetPC == PC + 8) + { + _Notify->BreakPoint(__FILE__,__LINE__); + } if (TargetPC == PC) { _Notify->BreakPoint(__FILE__,__LINE__); diff --git a/Source/Project64/N64 System/Recompiler/Code Section.cpp b/Source/Project64/N64 System/Recompiler/Code Section.cpp index 42047f863..1f47654d7 100644 --- a/Source/Project64/N64 System/Recompiler/Code Section.cpp +++ b/Source/Project64/N64 System/Recompiler/Code Section.cpp @@ -1273,12 +1273,17 @@ bool CCodeSection::GenerateX86Code ( DWORD Test ) break; } - if (m_DelaySlot && (CompilePC() & 0xFFC) != 0xFFC) + if (m_DelaySlot) { - m_CompilePC = m_Jump.JumpPC; - m_Jump.RegSet = m_RegWorkingSet; - m_Jump.FallThrough = true; - GenerateSectionLinkage(); + if ((CompilePC() & 0xFFC) != 0xFFC) + { + m_CompilePC = m_Jump.JumpPC; + m_Jump.RegSet = m_RegWorkingSet; + m_Jump.FallThrough = true; + GenerateSectionLinkage(); + } else { + CompileExit (m_Jump.JumpPC, m_Jump.TargetPC,m_RegWorkingSet,CExitInfo::Normal,true,NULL); + } m_NextInstruction = END_BLOCK; } else if (m_NextInstruction != END_BLOCK && m_CompilePC == ContinueSectionPC) @@ -1927,7 +1932,7 @@ bool CCodeSection::InheritParentInfo ( void ) bool CCodeSection::DisplaySectionInformation (DWORD ID, DWORD Test) { - if (!bX86Logging || m_SectionID == 0) + if (!bX86Logging) { return false; } @@ -1945,6 +1950,11 @@ bool CCodeSection::DisplaySectionInformation (DWORD ID, DWORD Test) void CCodeSection::DisplaySectionInformation (void) { + if (m_SectionID == 0) + { + return; + } + CPU_Message("====== Section %d ======",m_SectionID); CPU_Message("Start PC: %X",m_EnterPC); CPU_Message("End PC: %X",m_EndPC); diff --git a/Source/Project64/N64 System/Recompiler/Loop Analysis.cpp b/Source/Project64/N64 System/Recompiler/Loop Analysis.cpp index 112d827c6..e2fbe0a38 100644 --- a/Source/Project64/N64 System/Recompiler/Loop Analysis.cpp +++ b/Source/Project64/N64 System/Recompiler/Loop Analysis.cpp @@ -71,7 +71,7 @@ bool LoopAnalysis::SetupEnterSection ( CCodeSection * Section, bool & bChanged, CCodeSection * Parent = *iter; CPU_Message(__FUNCTION__ ": Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X",Parent->m_SectionID,m_Test,Parent->m_Test, Parent->m_CompiledLocation); - if (Parent->m_Test != m_Test && (m_EnterSection != Section || Parent->m_CompiledLocation == NULL)) + if (Parent->m_Test != m_Test && (m_EnterSection != Section || Parent->m_CompiledLocation == NULL) && Parent->m_InLoop) { CPU_Message(__FUNCTION__ ": Ignore Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X",Parent->m_SectionID,m_Test,Parent->m_Test, Parent->m_CompiledLocation); bSkipedSection = true; @@ -161,7 +161,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section) return false; } CPU_Message(" %08X: %s",m_PC,R4300iOpcodeName(m_Command.Hex,m_PC)); - CPU_Message(" %s state: %X value: %X",CRegName::GPR[1],m_Reg.MipsRegState(1),m_Reg.MipsRegLo(1)); + CPU_Message(" %s state: %X value: %X",CRegName::GPR[3],m_Reg.MipsRegState(3),m_Reg.MipsRegLo(3)); switch (m_Command.op) { case R4300i_SPECIAL: switch (m_Command.funct) { @@ -366,60 +366,66 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section) #endif break; case R4300i_BEQ: - m_NextInstruction = DELAY_SLOT; -#ifdef CHECKED_BUILD - if (m_Command.rs != 0 || m_Command.rt != 0) + if (m_PC + ((short)m_Command.offset << 2) + 4 != m_PC + 8) { + m_NextInstruction = DELAY_SLOT; +#ifdef CHECKED_BUILD + if (m_Command.rs != 0 || m_Command.rt != 0) + { + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (DWORD)-1) + { + _Notify->BreakPoint(__FILE__,__LINE__); + } + } else { + if (Section->m_Cont.TargetPC != (DWORD)-1) + { + //_Notify->BreakPoint(__FILE__,__LINE__); + } + } + if (Section->m_Jump.TargetPC != m_PC + ((short)m_Command.offset << 2) + 4) + { + //_Notify->BreakPoint(__FILE__,__LINE__); + } + if (m_PC == Section->m_Jump.TargetPC) + { + _Notify->BreakPoint(__FILE__,__LINE__); +#ifdef tofix + if (!DelaySlotEffectsCompare(m_PC,m_Command.rs,m_Command.rt)) { + Section->m_Jump.PermLoop = true; + } +#endif + } +#endif + } + break; + case R4300i_BNE: + case R4300i_BLEZ: + case R4300i_BGTZ: + if (m_PC + ((short)m_Command.offset << 2) + 4 != m_PC + 8) + { + m_NextInstruction = DELAY_SLOT; +#ifdef CHECKED_BUILD if (Section->m_Cont.TargetPC != m_PC + 8 && Section->m_ContinueSection != NULL && Section->m_Cont.TargetPC != (DWORD)-1) { _Notify->BreakPoint(__FILE__,__LINE__); } - } else { - if (Section->m_Cont.TargetPC != (DWORD)-1) - { - //_Notify->BreakPoint(__FILE__,__LINE__); - } - } - if (Section->m_Jump.TargetPC != m_PC + ((short)m_Command.offset << 2) + 4) - { - //_Notify->BreakPoint(__FILE__,__LINE__); - } - if (m_PC == Section->m_Jump.TargetPC) - { - _Notify->BreakPoint(__FILE__,__LINE__); -#ifdef tofix - if (!DelaySlotEffectsCompare(m_PC,m_Command.rs,m_Command.rt)) { - Section->m_Jump.PermLoop = true; - } -#endif - } -#endif - break; - case R4300i_BNE: - case R4300i_BLEZ: - case R4300i_BGTZ: - m_NextInstruction = DELAY_SLOT; -#ifdef CHECKED_BUILD - if (Section->m_Cont.TargetPC != m_PC + 8 && - Section->m_ContinueSection != NULL && - Section->m_Cont.TargetPC != (DWORD)-1) - { - _Notify->BreakPoint(__FILE__,__LINE__); - } - if (Section->m_Jump.TargetPC != m_PC + ((short)m_Command.offset << 2) + 4) - { - _Notify->BreakPoint(__FILE__,__LINE__); - } - if (m_PC == Section->m_Jump.TargetPC) - { - if (!DelaySlotEffectsCompare(m_PC,m_Command.rs,m_Command.rt) && !Section->m_Jump.PermLoop) + if (Section->m_Jump.TargetPC != m_PC + ((short)m_Command.offset << 2) + 4) { _Notify->BreakPoint(__FILE__,__LINE__); } - } + if (m_PC == Section->m_Jump.TargetPC) + { + if (!DelaySlotEffectsCompare(m_PC,m_Command.rs,m_Command.rt) && !Section->m_Jump.PermLoop) + { + _Notify->BreakPoint(__FILE__,__LINE__); + } + } #endif + } break; case R4300i_ADDI: case R4300i_ADDIU: @@ -976,16 +982,7 @@ void LoopAnalysis::SPECIAL_DSRAV ( void ) void LoopAnalysis::SPECIAL_ADD ( void ) { if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) { - m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo(m_Command.rs) + m_Reg.MipsRegLo(m_Command.rt); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32); - } else { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } + m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); } void LoopAnalysis::SPECIAL_ADDU ( void ) @@ -997,139 +994,37 @@ void LoopAnalysis::SPECIAL_ADDU ( void ) void LoopAnalysis::SPECIAL_SUB ( void ) { if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) { - m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo(m_Command.rs) - m_Reg.MipsRegLo(m_Command.rt); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32); - } else { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } + m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); } void LoopAnalysis::SPECIAL_SUBU ( void ) { if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) { - m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo(m_Command.rs) - m_Reg.MipsRegLo(m_Command.rt); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32); - } else { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } + m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); } void LoopAnalysis::SPECIAL_AND ( void ) { if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) { - if (m_Reg.Is64Bit(m_Command.rt) && m_Reg.Is64Bit(m_Command.rs)) { - m_Reg.SetMipsReg(m_Command.rd,m_Reg.MipsReg(m_Command.rt) & m_Reg.MipsReg(m_Command.rs)); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_64); - } else if (m_Reg.Is64Bit(m_Command.rt) || m_Reg.Is64Bit(m_Command.rs)) { - if (m_Reg.Is64Bit(m_Command.rt)) { - m_Reg.SetMipsReg(m_Command.rd, m_Reg.MipsReg(m_Command.rt) & m_Reg.MipsRegLo(m_Command.rs)); - } else { - m_Reg.SetMipsReg(m_Command.rd, m_Reg.MipsRegLo(m_Command.rt) & m_Reg.MipsReg(m_Command.rs)); - } - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::ConstantsType(m_Reg.MipsReg(m_Command.rd))); - } else { - m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo(m_Command.rt) & m_Reg.MipsRegLo(m_Command.rs); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32); - } - } else { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } + m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); } void LoopAnalysis::SPECIAL_OR ( void ) { if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) { - if (m_Reg.Is64Bit(m_Command.rt) && m_Reg.Is64Bit(m_Command.rs)) { - m_Reg.SetMipsReg(m_Command.rd,m_Reg.MipsReg(m_Command.rt) | m_Reg.MipsReg(m_Command.rs)); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_64); - } else if (m_Reg.Is64Bit(m_Command.rt) || m_Reg.Is64Bit(m_Command.rs)) { - if (m_Reg.Is64Bit(m_Command.rt)) { - m_Reg.SetMipsReg(m_Command.rd,m_Reg.MipsReg(m_Command.rt) | m_Reg.MipsRegLo(m_Command.rs)); - } else { - m_Reg.SetMipsReg(m_Command.rd,m_Reg.MipsRegLo(m_Command.rt) | m_Reg.MipsReg(m_Command.rs)); - } - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_64); - } else { - m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo(m_Command.rt) | m_Reg.MipsRegLo(m_Command.rs); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32); - } - } else { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } + m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); } void LoopAnalysis::SPECIAL_XOR ( void ) { if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) { - if (m_Reg.Is64Bit(m_Command.rt) && m_Reg.Is64Bit(m_Command.rs)) { - m_Reg.SetMipsReg(m_Command.rd,m_Reg.MipsReg(m_Command.rt) ^ m_Reg.MipsReg(m_Command.rs)); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_64); - } else if (m_Reg.Is64Bit(m_Command.rt) || m_Reg.Is64Bit(m_Command.rs)) { - if (m_Reg.Is64Bit(m_Command.rt)) { - m_Reg.SetMipsReg(m_Command.rd, m_Reg.MipsReg(m_Command.rt) ^ m_Reg.MipsRegLo(m_Command.rs)); - } else { - m_Reg.SetMipsReg(m_Command.rd, m_Reg.MipsRegLo(m_Command.rt) ^ m_Reg.MipsReg(m_Command.rs)); - } - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_64); - } else { - m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo(m_Command.rt) ^ m_Reg.MipsRegLo(m_Command.rs); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32); - } - } else { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } + m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); } void LoopAnalysis::SPECIAL_NOR ( void ) { if (m_Command.rd == 0) { return; } - if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd) - { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } - if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) { - if (m_Reg.Is64Bit(m_Command.rt) && m_Reg.Is64Bit(m_Command.rs)) { - m_Reg.SetMipsReg(m_Command.rd,~(m_Reg.MipsReg(m_Command.rt) | m_Reg.MipsReg(m_Command.rs))); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_64); - } else if (m_Reg.Is64Bit(m_Command.rt) || m_Reg.Is64Bit(m_Command.rs)) { - if (m_Reg.Is64Bit(m_Command.rt)) { - m_Reg.SetMipsReg(m_Command.rd, ~(m_Reg.MipsReg(m_Command.rt) | m_Reg.MipsRegLo(m_Command.rs))); - } else { - m_Reg.SetMipsReg(m_Command.rd, ~(m_Reg.MipsRegLo(m_Command.rt) | m_Reg.MipsReg(m_Command.rs))); - } - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_64); - } else { - m_Reg.MipsRegLo(m_Command.rd) = ~(m_Reg.MipsRegLo(m_Command.rt) | m_Reg.MipsRegLo(m_Command.rs)); - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32); - } - } else { - m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); - } + m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_MODIFIED); } void LoopAnalysis::SPECIAL_SLT ( void ) diff --git a/Source/Project64/N64 System/Recompiler/Recompiler Ops.cpp b/Source/Project64/N64 System/Recompiler/Recompiler Ops.cpp index a06d5ed67..e74a58916 100644 --- a/Source/Project64/N64 System/Recompiler/Recompiler Ops.cpp +++ b/Source/Project64/N64 System/Recompiler/Recompiler Ops.cpp @@ -32,6 +32,11 @@ void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc, if ( m_NextInstruction == NORMAL ) { CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC)); + if (m_CompilePC + ((short)m_Opcode.offset << 2) + 4 == m_CompilePC + 8) + { + return; + } + if ((m_CompilePC & 0xFFC) != 0xFFC) { switch (BranchType) { @@ -285,23 +290,35 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link if ( m_NextInstruction == NORMAL ) { CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC)); - if (!bLinkBlocks()) + if (!bLinkBlocks() || (m_CompilePC & 0xFFC) == 0xFFC) { - m_Section->m_Jump.JumpPC = m_CompilePC; + m_Section->m_Jump.JumpPC = m_CompilePC; m_Section->m_Jump.TargetPC = m_CompilePC + ((short)m_Opcode.offset << 2) + 4; - if (m_Section->m_JumpSection != NULL) { - m_Section->m_Jump.BranchLabel.Format("Section_%d",((CCodeSection *)m_Section->m_JumpSection)->m_SectionID); - } else { - m_Section->m_Jump.BranchLabel = "ExitBlock"; + m_Section->m_Cont.JumpPC = m_CompilePC; + m_Section->m_Cont.TargetPC = m_CompilePC + 8; + } else { + if (m_Section->m_Jump.JumpPC != m_CompilePC) + { + _Notify->BreakPoint(__FILE__,__LINE__); } - - m_Section->m_Cont.JumpPC = m_CompilePC; - m_Section->m_Cont.TargetPC = m_CompilePC + 8; - if (m_Section->m_ContinueSection != NULL) { - m_Section->m_Cont.BranchLabel.Format("Section_%d",((CCodeSection *)m_Section->m_ContinueSection)->m_SectionID); - } else { - m_Section->m_Cont.BranchLabel = "ExitBlock"; + if (m_Section->m_Cont.JumpPC != m_CompilePC) + { + _Notify->BreakPoint(__FILE__,__LINE__); } + if (m_Section->m_Cont.TargetPC != m_CompilePC + 8) + { + _Notify->BreakPoint(__FILE__,__LINE__); + } + } + if (m_Section->m_JumpSection != NULL) { + m_Section->m_Jump.BranchLabel.Format("Section_%d",((CCodeSection *)m_Section->m_JumpSection)->m_SectionID); + } else { + m_Section->m_Jump.BranchLabel = "ExitBlock"; + } + if (m_Section->m_ContinueSection != NULL) { + m_Section->m_Cont.BranchLabel.Format("Section_%d",((CCodeSection *)m_Section->m_ContinueSection)->m_SectionID); + } else { + m_Section->m_Cont.BranchLabel = "ExitBlock"; } m_Section->m_Jump.FallThrough = TRUE; m_Section->m_Jump.LinkLocation = NULL; @@ -317,14 +334,45 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link } CompareFunc(); ResetX86Protection(); + + m_Section->m_Cont.RegSet = m_RegWorkingSet; + if ((m_CompilePC & 0xFFC) == 0xFFC) + { + if (m_Section->m_Cont.FallThrough) { _Notify->BreakPoint(__FILE__,__LINE__); } + + if (m_Section->m_Jump.LinkLocation != NULL) { + SetJump32(m_Section->m_Jump.LinkLocation,(DWORD *)m_RecompPos); + m_Section->m_Jump.LinkLocation = NULL; + if (m_Section->m_Jump.LinkLocation2 != NULL) { + SetJump32(m_Section->m_Jump.LinkLocation2,(DWORD *)m_RecompPos); + m_Section->m_Jump.LinkLocation2 = NULL; + } + } + + MoveConstToVariable(m_Section->m_Jump.TargetPC,&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation"); + OverflowDelaySlot(false); + CPU_Message(" "); + CPU_Message(" %s:",m_Section->m_Cont.BranchLabel.c_str()); + if (m_Section->m_Cont.LinkLocation != NULL) { + SetJump32(m_Section->m_Cont.LinkLocation,(DWORD *)m_RecompPos); + m_Section->m_Cont.LinkLocation = NULL; + if (m_Section->m_Cont.LinkLocation2 != NULL) { + SetJump32(m_Section->m_Cont.LinkLocation2,(DWORD *)m_RecompPos); + m_Section->m_Cont.LinkLocation2 = NULL; + } + } + m_Section->CompileExit(m_CompilePC, m_CompilePC + 8,m_Section->m_Cont.RegSet,CExitInfo::Normal,TRUE,NULL); + return; + } else { + m_NextInstruction = DO_DELAY_SLOT; + } + if (bLinkBlocks()) { m_Section->m_Jump.RegSet = m_RegWorkingSet; - m_Section->m_Cont.RegSet = m_RegWorkingSet; m_Section->GenerateSectionLinkage(); m_NextInstruction = END_BLOCK; } else { - m_Section->m_Cont.RegSet = m_RegWorkingSet; if (m_Section->m_Cont.FallThrough) { if (m_Section->m_Jump.LinkLocation != NULL) @@ -333,36 +381,6 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link } m_Section->GenerateSectionLinkage(); m_NextInstruction = END_BLOCK; - } else { - if ((m_CompilePC & 0xFFC) == 0xFFC) - { - if (m_Section->m_Cont.FallThrough) { _Notify->BreakPoint(__FILE__,__LINE__); } - - if (m_Section->m_Jump.LinkLocation != NULL) { - SetJump32(m_Section->m_Jump.LinkLocation,(DWORD *)m_RecompPos); - m_Section->m_Jump.LinkLocation = NULL; - if (m_Section->m_Jump.LinkLocation2 != NULL) { - SetJump32(m_Section->m_Jump.LinkLocation2,(DWORD *)m_RecompPos); - m_Section->m_Jump.LinkLocation2 = NULL; - } - } - MoveConstToVariable(m_Section->m_Jump.TargetPC,&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation"); - OverflowDelaySlot(false); - CPU_Message(" "); - CPU_Message(" %s:",m_Section->m_Cont.BranchLabel.c_str()); - if (m_Section->m_Cont.LinkLocation != NULL) { - SetJump32(m_Section->m_Cont.LinkLocation,(DWORD *)m_RecompPos); - m_Section->m_Cont.LinkLocation = NULL; - if (m_Section->m_Cont.LinkLocation2 != NULL) { - SetJump32(m_Section->m_Cont.LinkLocation2,(DWORD *)m_RecompPos); - m_Section->m_Cont.LinkLocation2 = NULL; - } - } - m_Section->CompileExit(m_CompilePC, m_CompilePC + 8,m_Section->m_Cont.RegSet,CExitInfo::Normal,TRUE,NULL); - return; - } else { - m_NextInstruction = DO_DELAY_SLOT; - } } } } else if (m_NextInstruction == DELAY_SLOT_DONE ) {