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;
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:

View File

@ -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__);

View File

@ -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);

View File

@ -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 )

View File

@ -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 ) {