More bug fixing related to changes ABL

This commit is contained in:
zilmar 2012-10-22 19:02:53 +11:00
parent d8d5379e2a
commit 4a3073af6d
5 changed files with 208 additions and 235 deletions

View File

@ -400,9 +400,16 @@ void CMipsMemoryVM::Compile_LW (x86Reg Reg, DWORD VAddr ) {
} }
break; break;
case 0x04100000: case 0x04100000:
if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { _Notify->DisplayError("Compile_LW\nFailed to translate address: %X",VAddr); } {
sprintf(VarName,"m_RDRAM + %X",PAddr); static DWORD TempValue = 0;
MoveVariableToX86reg(PAddr + m_RDRAM,VarName,Reg); 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; break;
case 0x04300000: case 0x04300000:
switch (PAddr) { switch (PAddr) {
@ -1057,10 +1064,19 @@ void CMipsMemoryVM::Compile_SW_Register (x86Reg Reg, DWORD VAddr )
} }
break; break;
case 0x04100000: case 0x04100000:
CPU_Message(" Should be moving %s in to %X ?!?",x86_Name(Reg),VAddr); if (PAddr == 0x0410000C)
sprintf(VarName,"m_RDRAM + %X",PAddr); {
MoveX86regToVariable(Reg,PAddr + m_RDRAM,VarName); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount()-CountPerOp());
if (_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { _Notify->DisplayError("Compile_SW_Register\ntrying to store at %X?",VAddr); } 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: case 0x04300000:
switch (PAddr) { switch (PAddr) {
case 0x04300000: case 0x04300000:
@ -1630,7 +1646,14 @@ int CMipsMemoryVM::LB_NonMemory ( DWORD /*PAddr*/, DWORD * Value, BOOL /*SignExt
// return TRUE; // 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__); _Notify->BreakPoint(__FILE__,__LINE__);
// switch (PAddr & 0xFFF00000) { // switch (PAddr & 0xFFF00000) {
// default: // default:

View File

@ -88,7 +88,7 @@ bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSe
if (Section == NULL) 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) if (Section == NULL)
{ {
_Notify->BreakPoint(__FILE__,__LINE__); _Notify->BreakPoint(__FILE__,__LINE__);
@ -100,7 +100,7 @@ bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSe
m_SectionMap.insert(SectionMap::value_type(TargetPC,Section)); m_SectionMap.insert(SectionMap::value_type(TargetPC,Section));
} }
Section->AddParent(CurrentSection); Section->AddParent(CurrentSection);
if (TargetPC < CurrentPC && TargetPC != m_VAddrEnter) if (TargetPC <= CurrentPC && TargetPC != m_VAddrEnter)
{ {
CCodeSection * SplitSection = NULL; CCodeSection * SplitSection = NULL;
for (SectionMap::const_iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++) 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) if (SplitSection->m_EndPC >= TargetPC)
{ {
CPU_Message(__FUNCTION__ ": Split Section: %d with section: %d",SplitSection->m_SectionID, Section->m_SectionID);
CCodeSection * BaseSection = Section; CCodeSection * BaseSection = Section;
BaseSection->m_EndPC = SplitSection->m_EndPC; BaseSection->m_EndPC = SplitSection->m_EndPC;
BaseSection->SetJumpAddress(SplitSection->m_Jump.JumpPC, SplitSection->m_Jump.TargetPC,SplitSection->m_Jump.PermLoop); 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: case R4300i_REGIMM_BLTZ:
TargetPC = PC + ((short)Command.offset << 2) + 4; TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC + 8)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (TargetPC == PC) if (TargetPC == PC)
{ {
_Notify->BreakPoint(__FILE__,__LINE__); _Notify->BreakPoint(__FILE__,__LINE__);
@ -405,6 +410,10 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
case R4300i_REGIMM_BGEZ: case R4300i_REGIMM_BGEZ:
case R4300i_REGIMM_BGEZAL: case R4300i_REGIMM_BGEZAL:
TargetPC = PC + ((short)Command.offset << 2) + 4; TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC + 8)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
IncludeDelaySlot = true; IncludeDelaySlot = true;
if (Command.rs != 0) if (Command.rs != 0)
{ {
@ -455,6 +464,10 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
break; break;
case R4300i_BEQ: case R4300i_BEQ:
TargetPC = PC + ((short)Command.offset << 2) + 4; TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC + 8)
{
TargetPC = (DWORD)-1;
} else {
if (Command.rs != 0 || Command.rt != 0) if (Command.rs != 0 || Command.rt != 0)
{ {
ContinuePC = PC + 8; ContinuePC = PC + 8;
@ -462,17 +475,26 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
PermLoop = true; PermLoop = true;
} }
IncludeDelaySlot = true; IncludeDelaySlot = true;
}
break; break;
case R4300i_BNE: case R4300i_BNE:
case R4300i_BLEZ: case R4300i_BLEZ:
case R4300i_BGTZ: case R4300i_BGTZ:
TargetPC = PC + ((short)Command.offset << 2) + 4; TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC + 8)
{
TargetPC = (DWORD)-1;
} else {
if (TargetPC == PC) if (TargetPC == PC)
{ {
_Notify->BreakPoint(__FILE__,__LINE__); if (!DelaySlotEffectsCompare(PC,Command.rs,Command.rt))
{
PermLoop = true;
}
} }
ContinuePC = PC + 8; ContinuePC = PC + 8;
IncludeDelaySlot = true; IncludeDelaySlot = true;
}
break; break;
case R4300i_CP0: case R4300i_CP0:
switch (Command.rs) switch (Command.rs)
@ -502,14 +524,19 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
break; break;
case R4300i_CP1: case R4300i_CP1:
switch (Command.fmt) { switch (Command.fmt) {
case R4300i_COP1_MF: case R4300i_COP1_CF: case R4300i_COP1_MT: case R4300i_COP1_CT: case R4300i_COP1_MF: case R4300i_COP1_DMF: case R4300i_COP1_CF: case R4300i_COP1_MT:
case R4300i_COP1_S: case R4300i_COP1_D: case R4300i_COP1_W: case R4300i_COP1_L: 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; break;
case R4300i_COP1_BC: case R4300i_COP1_BC:
switch (Command.ft) { switch (Command.ft) {
case R4300i_COP1_BC_BCF: case R4300i_COP1_BC_BCF:
case R4300i_COP1_BC_BCT: case R4300i_COP1_BC_BCT:
TargetPC = PC + ((short)Command.offset << 2) + 4; TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC + 8)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (TargetPC == PC) if (TargetPC == PC)
{ {
_Notify->BreakPoint(__FILE__,__LINE__); _Notify->BreakPoint(__FILE__,__LINE__);

View File

@ -1273,12 +1273,17 @@ bool CCodeSection::GenerateX86Code ( DWORD Test )
break; break;
} }
if (m_DelaySlot && (CompilePC() & 0xFFC) != 0xFFC) if (m_DelaySlot)
{
if ((CompilePC() & 0xFFC) != 0xFFC)
{ {
m_CompilePC = m_Jump.JumpPC; m_CompilePC = m_Jump.JumpPC;
m_Jump.RegSet = m_RegWorkingSet; m_Jump.RegSet = m_RegWorkingSet;
m_Jump.FallThrough = true; m_Jump.FallThrough = true;
GenerateSectionLinkage(); GenerateSectionLinkage();
} else {
CompileExit (m_Jump.JumpPC, m_Jump.TargetPC,m_RegWorkingSet,CExitInfo::Normal,true,NULL);
}
m_NextInstruction = END_BLOCK; m_NextInstruction = END_BLOCK;
} }
else if (m_NextInstruction != END_BLOCK && m_CompilePC == ContinueSectionPC) else if (m_NextInstruction != END_BLOCK && m_CompilePC == ContinueSectionPC)
@ -1927,7 +1932,7 @@ bool CCodeSection::InheritParentInfo ( void )
bool CCodeSection::DisplaySectionInformation (DWORD ID, DWORD Test) bool CCodeSection::DisplaySectionInformation (DWORD ID, DWORD Test)
{ {
if (!bX86Logging || m_SectionID == 0) if (!bX86Logging)
{ {
return false; return false;
} }
@ -1945,6 +1950,11 @@ bool CCodeSection::DisplaySectionInformation (DWORD ID, DWORD Test)
void CCodeSection::DisplaySectionInformation (void) void CCodeSection::DisplaySectionInformation (void)
{ {
if (m_SectionID == 0)
{
return;
}
CPU_Message("====== Section %d ======",m_SectionID); CPU_Message("====== Section %d ======",m_SectionID);
CPU_Message("Start PC: %X",m_EnterPC); CPU_Message("Start PC: %X",m_EnterPC);
CPU_Message("End PC: %X",m_EndPC); CPU_Message("End PC: %X",m_EndPC);

View File

@ -71,7 +71,7 @@ bool LoopAnalysis::SetupEnterSection ( CCodeSection * Section, bool & bChanged,
CCodeSection * Parent = *iter; 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); 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); 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; bSkipedSection = true;
@ -161,7 +161,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section)
return false; return false;
} }
CPU_Message(" %08X: %s",m_PC,R4300iOpcodeName(m_Command.Hex,m_PC)); 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) { switch (m_Command.op) {
case R4300i_SPECIAL: case R4300i_SPECIAL:
switch (m_Command.funct) { switch (m_Command.funct) {
@ -366,6 +366,8 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section)
#endif #endif
break; break;
case R4300i_BEQ: case R4300i_BEQ:
if (m_PC + ((short)m_Command.offset << 2) + 4 != m_PC + 8)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (m_Command.rs != 0 || m_Command.rt != 0) if (m_Command.rs != 0 || m_Command.rt != 0)
@ -396,10 +398,13 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section)
#endif #endif
} }
#endif #endif
}
break; break;
case R4300i_BNE: case R4300i_BNE:
case R4300i_BLEZ: case R4300i_BLEZ:
case R4300i_BGTZ: case R4300i_BGTZ:
if (m_PC + ((short)m_Command.offset << 2) + 4 != m_PC + 8)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (Section->m_Cont.TargetPC != m_PC + 8 && if (Section->m_Cont.TargetPC != m_PC + 8 &&
@ -420,6 +425,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section)
} }
} }
#endif #endif
}
break; break;
case R4300i_ADDI: case R4300i_ADDI:
case R4300i_ADDIU: case R4300i_ADDIU:
@ -976,16 +982,7 @@ void LoopAnalysis::SPECIAL_DSRAV ( void )
void LoopAnalysis::SPECIAL_ADD ( void ) void LoopAnalysis::SPECIAL_ADD ( void )
{ {
if (m_Command.rd == 0) { return; } 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); 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);
}
} }
void LoopAnalysis::SPECIAL_ADDU ( void ) void LoopAnalysis::SPECIAL_ADDU ( void )
@ -997,139 +994,37 @@ void LoopAnalysis::SPECIAL_ADDU ( void )
void LoopAnalysis::SPECIAL_SUB ( void ) void LoopAnalysis::SPECIAL_SUB ( void )
{ {
if (m_Command.rd == 0) { return; } 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); 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);
}
} }
void LoopAnalysis::SPECIAL_SUBU ( void ) void LoopAnalysis::SPECIAL_SUBU ( void )
{ {
if (m_Command.rd == 0) { return; } 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); 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);
}
} }
void LoopAnalysis::SPECIAL_AND ( void ) void LoopAnalysis::SPECIAL_AND ( void )
{ {
if (m_Command.rd == 0) { return; } 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); 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);
}
} }
void LoopAnalysis::SPECIAL_OR ( void ) void LoopAnalysis::SPECIAL_OR ( void )
{ {
if (m_Command.rd == 0) { return; } 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); 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);
}
} }
void LoopAnalysis::SPECIAL_XOR ( void ) void LoopAnalysis::SPECIAL_XOR ( void )
{ {
if (m_Command.rd == 0) { return; } 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); 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);
}
} }
void LoopAnalysis::SPECIAL_NOR ( void ) void LoopAnalysis::SPECIAL_NOR ( void )
{ {
if (m_Command.rd == 0) { return; } 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); 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);
}
} }
void LoopAnalysis::SPECIAL_SLT ( void ) void LoopAnalysis::SPECIAL_SLT ( void )

View File

@ -32,6 +32,11 @@ void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc,
if ( m_NextInstruction == NORMAL ) { if ( m_NextInstruction == NORMAL ) {
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC)); 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) if ((m_CompilePC & 0xFFC) != 0xFFC)
{ {
switch (BranchType) { switch (BranchType) {
@ -285,24 +290,36 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link
if ( m_NextInstruction == NORMAL ) { if ( m_NextInstruction == NORMAL ) {
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC)); 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; m_Section->m_Jump.TargetPC = m_CompilePC + ((short)m_Opcode.offset << 2) + 4;
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__);
}
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) { if (m_Section->m_JumpSection != NULL) {
m_Section->m_Jump.BranchLabel.Format("Section_%d",((CCodeSection *)m_Section->m_JumpSection)->m_SectionID); m_Section->m_Jump.BranchLabel.Format("Section_%d",((CCodeSection *)m_Section->m_JumpSection)->m_SectionID);
} else { } else {
m_Section->m_Jump.BranchLabel = "ExitBlock"; m_Section->m_Jump.BranchLabel = "ExitBlock";
} }
m_Section->m_Cont.JumpPC = m_CompilePC;
m_Section->m_Cont.TargetPC = m_CompilePC + 8;
if (m_Section->m_ContinueSection != NULL) { if (m_Section->m_ContinueSection != NULL) {
m_Section->m_Cont.BranchLabel.Format("Section_%d",((CCodeSection *)m_Section->m_ContinueSection)->m_SectionID); m_Section->m_Cont.BranchLabel.Format("Section_%d",((CCodeSection *)m_Section->m_ContinueSection)->m_SectionID);
} else { } else {
m_Section->m_Cont.BranchLabel = "ExitBlock"; m_Section->m_Cont.BranchLabel = "ExitBlock";
} }
}
m_Section->m_Jump.FallThrough = TRUE; m_Section->m_Jump.FallThrough = TRUE;
m_Section->m_Jump.LinkLocation = NULL; m_Section->m_Jump.LinkLocation = NULL;
m_Section->m_Jump.LinkLocation2 = NULL; m_Section->m_Jump.LinkLocation2 = NULL;
@ -317,23 +334,8 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link
} }
CompareFunc(); CompareFunc();
ResetX86Protection(); ResetX86Protection();
if (bLinkBlocks())
{
m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->m_Cont.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)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK;
} else {
if ((m_CompilePC & 0xFFC) == 0xFFC) if ((m_CompilePC & 0xFFC) == 0xFFC)
{ {
if (m_Section->m_Cont.FallThrough) { _Notify->BreakPoint(__FILE__,__LINE__); } if (m_Section->m_Cont.FallThrough) { _Notify->BreakPoint(__FILE__,__LINE__); }
@ -346,6 +348,7 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link
m_Section->m_Jump.LinkLocation2 = NULL; m_Section->m_Jump.LinkLocation2 = NULL;
} }
} }
MoveConstToVariable(m_Section->m_Jump.TargetPC,&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation"); MoveConstToVariable(m_Section->m_Jump.TargetPC,&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation");
OverflowDelaySlot(false); OverflowDelaySlot(false);
CPU_Message(" "); CPU_Message(" ");
@ -363,6 +366,21 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link
} else { } else {
m_NextInstruction = DO_DELAY_SLOT; m_NextInstruction = DO_DELAY_SLOT;
} }
if (bLinkBlocks())
{
m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK;
} else {
if (m_Section->m_Cont.FallThrough)
{
if (m_Section->m_Jump.LinkLocation != NULL)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK;
} }
} }
} else if (m_NextInstruction == DELAY_SLOT_DONE ) { } else if (m_NextInstruction == DELAY_SLOT_DONE ) {