Changed handling of delay slot which goes over a 4k boundary to be executed by the interpret code instead of trying to be compiler. This means we do not have to care about the self mod of the delay slot
This commit is contained in:
parent
5344507496
commit
f52f82e8b5
|
@ -44,7 +44,10 @@ CN64System::CN64System ( CPlugins * Plugins, bool SavesReadOnly ) :
|
|||
m_SystemTimer(m_NextTimer),
|
||||
m_DMAUsed(false),
|
||||
m_CPU_Handle(NULL),
|
||||
m_CPU_ThreadID(0)
|
||||
m_CPU_ThreadID(0),
|
||||
m_TestTimer(false),
|
||||
m_NextInstruction(0),
|
||||
m_JumpToLocation(0)
|
||||
{
|
||||
m_hPauseEvent = CreateEvent(NULL,true,false,NULL);
|
||||
m_Limitor.SetHertz(_Settings->LoadDword(Game_ScreenHertz));
|
||||
|
@ -522,6 +525,13 @@ bool CN64System::SetActiveSystem( bool bActive )
|
|||
{
|
||||
m_Reg.SetAsCurrentSystem();
|
||||
|
||||
if (_System)
|
||||
{
|
||||
_System->m_TestTimer = R4300iOp::m_TestTimer;
|
||||
_System->m_NextInstruction = R4300iOp::m_NextInstruction;
|
||||
_System->m_JumpToLocation = R4300iOp::m_JumpToLocation;
|
||||
}
|
||||
|
||||
_System = this;
|
||||
if (_BaseSystem == this)
|
||||
{
|
||||
|
@ -538,6 +548,9 @@ bool CN64System::SetActiveSystem( bool bActive )
|
|||
_SystemEvents = this;
|
||||
_NextTimer = &m_NextTimer;
|
||||
_Plugins = m_Plugins;
|
||||
R4300iOp::m_TestTimer = m_TestTimer;
|
||||
R4300iOp::m_NextInstruction = m_NextInstruction;
|
||||
R4300iOp::m_JumpToLocation = m_JumpToLocation;
|
||||
|
||||
if (!m_bInitilized)
|
||||
{
|
||||
|
|
|
@ -125,6 +125,9 @@ private:
|
|||
int m_NextTimer;
|
||||
bool m_DMAUsed;
|
||||
DWORD m_Buttons[4];
|
||||
BOOL m_TestTimer;
|
||||
DWORD m_NextInstruction;
|
||||
DWORD m_JumpToLocation;
|
||||
|
||||
//When Syncing cores this is the PC where it last Sync'ed correctly
|
||||
DWORD m_LastSuccessSyncPC[10];
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos, bool bDelaySlot) :
|
||||
CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos) :
|
||||
m_VAddrEnter(VAddrEnter),
|
||||
m_VAddrFirst(VAddrEnter),
|
||||
m_VAddrLast(VAddrEnter),
|
||||
m_CompiledLocation(RecompPos),
|
||||
m_NoOfSections(1),
|
||||
m_EnterSection(this, VAddrEnter, 1),
|
||||
m_bDelaySlot(bDelaySlot),
|
||||
m_Test(1)
|
||||
{
|
||||
if (_TransVaddr->VAddrToRealAddr(VAddrEnter,*(reinterpret_cast<void **>(&m_MemLocation[0]))))
|
||||
|
@ -35,46 +34,30 @@ bool CCodeBlock::AnalyseBlock ( void )
|
|||
|
||||
bool CCodeBlock::Compile()
|
||||
{
|
||||
if (m_bDelaySlot)
|
||||
{
|
||||
CPU_Message("====== Delay Block ======");
|
||||
} else {
|
||||
CPU_Message("====== Code Block ======");
|
||||
}
|
||||
CPU_Message("====== Code Block ======");
|
||||
CPU_Message("x86 code at: %X",CompiledLocation());
|
||||
CPU_Message("Start of Block: %X",VAddrEnter() );
|
||||
CPU_Message("No of Sections: %d",NoOfSections() );
|
||||
CPU_Message("====== recompiled code ======");
|
||||
|
||||
if (m_bDelaySlot)
|
||||
{
|
||||
Pop(x86_EAX);
|
||||
MoveX86regToVariable(x86_EAX,_PROGRAM_COUNTER,"_PROGRAM_COUNTER");
|
||||
} else {
|
||||
EnterCodeBlock();
|
||||
EnterCodeBlock();
|
||||
|
||||
/*if (bLinkBlocks()) {
|
||||
for (int i = 0; i < m_NoOfSections; i ++) {
|
||||
m_EnterSection.DisplaySectionInformation(i + 1,NextTest());
|
||||
}
|
||||
}*/
|
||||
if (_SyncSystem) {
|
||||
//if ((DWORD)BlockInfo.CompiledLocation == 0x60A7B73B) { X86BreakPoint(__FILE__,__LINE__); }
|
||||
//MoveConstToVariable((DWORD)BlockInfo.CompiledLocation,&CurrentBlock,"CurrentBlock");
|
||||
}
|
||||
|
||||
if (m_bDelaySlot)
|
||||
{
|
||||
m_EnterSection.GenerateX86Code(NextTest());
|
||||
if (bLinkBlocks()) {
|
||||
while (m_EnterSection.GenerateX86Code(NextTest()));
|
||||
} else {
|
||||
/*if (bLinkBlocks()) {
|
||||
for (int i = 0; i < m_NoOfSections; i ++) {
|
||||
m_EnterSection.DisplaySectionInformation(i + 1,NextTest());
|
||||
}
|
||||
}*/
|
||||
if (_SyncSystem) {
|
||||
//if ((DWORD)BlockInfo.CompiledLocation == 0x60A7B73B) { X86BreakPoint(__FILE__,__LINE__); }
|
||||
//MoveConstToVariable((DWORD)BlockInfo.CompiledLocation,&CurrentBlock,"CurrentBlock");
|
||||
}
|
||||
|
||||
if (bLinkBlocks()) {
|
||||
while (m_EnterSection.GenerateX86Code(NextTest()));
|
||||
} else {
|
||||
if (!m_EnterSection.GenerateX86Code(NextTest()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!m_EnterSection.GenerateX86Code(NextTest()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
CompileExitCode();
|
||||
|
|
|
@ -2,7 +2,7 @@ class CCodeBlock :
|
|||
private CRecompilerOps
|
||||
{
|
||||
public:
|
||||
CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos, bool bDelaySlot );
|
||||
CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos );
|
||||
|
||||
bool Compile ( void );
|
||||
|
||||
|
@ -12,7 +12,6 @@ public:
|
|||
inline BYTE * CompiledLocation ( void ) const { return m_CompiledLocation; }
|
||||
inline int NoOfSections ( void ) const { return m_NoOfSections; }
|
||||
inline const CCodeSection & EnterSection ( void ) const { return m_EnterSection; }
|
||||
inline bool bDelaySlot ( void ) const { return m_bDelaySlot; }
|
||||
inline const MD5Digest & Hash ( void ) const { return m_Hash; }
|
||||
|
||||
inline void SetVAddrFirst ( DWORD VAddr ) { m_VAddrFirst = VAddr; }
|
||||
|
@ -38,7 +37,6 @@ private:
|
|||
DWORD m_VAddrLast; // the address of the first opcode in the block
|
||||
BYTE * m_CompiledLocation; // What address is this compiled at
|
||||
int m_NoOfSections; // The number of sections this block uses
|
||||
bool m_bDelaySlot;
|
||||
CCodeSection m_EnterSection;
|
||||
DWORD m_Test;
|
||||
MD5Digest m_Hash;
|
||||
|
|
|
@ -82,7 +82,6 @@ CCodeSection::CCodeSection( CCodeBlock * CodeBlock, DWORD EnterPC, DWORD ID) :
|
|||
m_JumpSection(NULL),
|
||||
m_LinkAllowed(true),
|
||||
m_CompiledLocation(NULL),
|
||||
m_DelaySlotSection(CodeBlock? CodeBlock->bDelaySlot() : false),
|
||||
m_Test(0),
|
||||
m_Test2(0),
|
||||
m_InLoop(false)
|
||||
|
@ -313,6 +312,8 @@ void CCodeSection::GenerateSectionLinkage (void)
|
|||
}
|
||||
|
||||
if ((CompilePC() & 0xFFC) == 0xFFC) {
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
#ifdef tofix
|
||||
//Handle Fall througth
|
||||
BYTE * Jump = NULL;
|
||||
for (i = 0; i < 2; i ++) {
|
||||
|
@ -366,6 +367,7 @@ void CCodeSection::GenerateSectionLinkage (void)
|
|||
JmpDirectReg(x86_EAX);
|
||||
ExitCodeBlock();
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if (!g_UseLinking) {
|
||||
if (CRecompilerOps::m_CompilePC == m_Jump.TargetPC && (m_Cont.FallThrough == false)) {
|
||||
|
@ -907,14 +909,9 @@ bool CCodeSection::GenerateX86Code ( DWORD Test )
|
|||
m_RegWorkingSet = m_RegEnter;
|
||||
m_CompiledLocation = m_RecompPos;
|
||||
m_CompilePC = m_EnterPC;
|
||||
m_NextInstruction = m_DelaySlotSection ? END_BLOCK : NORMAL;
|
||||
m_NextInstruction = NORMAL;
|
||||
m_Section = this;
|
||||
|
||||
if (m_DelaySlotSection)
|
||||
{
|
||||
m_Cont.JumpPC = m_EnterPC;
|
||||
}
|
||||
|
||||
if (m_CompilePC < m_BlockInfo->VAddrFirst())
|
||||
{
|
||||
m_BlockInfo->SetVAddrFirst(m_CompilePC);
|
||||
|
@ -1250,6 +1247,7 @@ bool CCodeSection::GenerateX86Code ( DWORD Test )
|
|||
if (m_NextInstruction == DO_DELAY_SLOT)
|
||||
{
|
||||
DisplayError("Wanting to do delay slot over end of block");
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
}
|
||||
if (m_NextInstruction == NORMAL) {
|
||||
CompileExit (m_CompilePC, m_CompilePC + 4,m_RegWorkingSet,CExitInfo::Normal,true,NULL);
|
||||
|
@ -1272,11 +1270,6 @@ bool CCodeSection::GenerateX86Code ( DWORD Test )
|
|||
break;
|
||||
}
|
||||
} while (m_NextInstruction != END_BLOCK);
|
||||
|
||||
if (m_DelaySlotSection)
|
||||
{
|
||||
CompileExit (m_CompilePC, -1,m_RegWorkingSet,CExitInfo::Normal,true,NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,12 +34,8 @@ public:
|
|||
DWORD m_Test;
|
||||
DWORD m_Test2;
|
||||
BYTE * m_CompiledLocation;
|
||||
bool m_DelaySlotSection;
|
||||
bool m_InLoop;
|
||||
|
||||
/*
|
||||
|
||||
|
||||
/* Register Info */
|
||||
CRegInfo m_RegEnter;
|
||||
|
||||
|
@ -47,7 +43,6 @@ public:
|
|||
CJumpInfo m_Jump;
|
||||
CJumpInfo m_Cont;
|
||||
|
||||
|
||||
private:
|
||||
void AddParent ( CCodeSection * Parent );
|
||||
void UnlinkParent ( CCodeSection * Parent, bool ContinueSection );
|
||||
|
|
|
@ -677,72 +677,6 @@ void CRecompiler::ResetRecompCode()
|
|||
m_Functions.clear();
|
||||
}
|
||||
|
||||
BYTE * CRecompiler::CompileDelaySlot(DWORD PC)
|
||||
{
|
||||
if (LookUpMode() == FuncFind_VirtualLookup)
|
||||
{
|
||||
int Index = PC >> 0xC;
|
||||
BYTE * delayFunc = DelaySlotTable()[Index];
|
||||
if (delayFunc)
|
||||
{
|
||||
return delayFunc;
|
||||
}
|
||||
|
||||
WriteTraceF(TraceRecompiler,"Compile Delay Slot: %X",PC);
|
||||
if ((PC & 0xFFC) != 0) {
|
||||
DisplayError("Why are you compiling the Delay Slot at %X",PC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CheckRecompMem();
|
||||
|
||||
CCodeBlock CodeBlock(PC, RecompPos(), true);
|
||||
if (!CodeBlock.Compile())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CCompiledFunc * Func = new CCompiledFunc(CodeBlock);
|
||||
delayFunc = (BYTE *)Func->Function();
|
||||
DelaySlotTable()[Index] = delayFunc;
|
||||
delete Func;
|
||||
return delayFunc;
|
||||
} else {
|
||||
DWORD pAddr;
|
||||
if (_TransVaddr->TranslateVaddr(PC,pAddr))
|
||||
{
|
||||
int Index = pAddr >> 0xC;
|
||||
BYTE * delayFunc = DelaySlotTable()[Index];
|
||||
if (delayFunc)
|
||||
{
|
||||
return delayFunc;
|
||||
}
|
||||
WriteTraceF(TraceRecompiler,"Compile Delay Slot: %X",pAddr);
|
||||
if ((pAddr & 0xFFC) != 0) {
|
||||
DisplayError("Why are you compiling the Delay Slot at %X",pAddr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CheckRecompMem();
|
||||
|
||||
CCodeBlock CodeBlock(PC, RecompPos(), true);
|
||||
if (!CodeBlock.Compile())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CCompiledFunc * Func = new CCompiledFunc(CodeBlock);
|
||||
delayFunc = (BYTE *)Func->Function();
|
||||
DelaySlotTable()[Index] = delayFunc;
|
||||
delete Func;
|
||||
return delayFunc;
|
||||
} else {
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CRecompiler::RecompilerMain_ChangeMemory ( void )
|
||||
{
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
|
@ -916,7 +850,7 @@ CCompiledFunc * CRecompiler::CompilerCode ( void )
|
|||
DWORD StartTime = timeGetTime();
|
||||
WriteTraceF(TraceRecompiler,"Compile Block-Start: Program Counter: %X pAddr: %X",PROGRAM_COUNTER,pAddr);
|
||||
|
||||
CCodeBlock CodeBlock(PROGRAM_COUNTER, RecompPos(),false);
|
||||
CCodeBlock CodeBlock(PROGRAM_COUNTER, RecompPos());
|
||||
if (!CodeBlock.Compile())
|
||||
{
|
||||
return NULL;
|
||||
|
|
|
@ -28,7 +28,6 @@ public:
|
|||
void ResetRecompCode ( void );
|
||||
|
||||
bool GenerateX86Code (CCodeBlock & BlockInfo, CCodeSection * Section, DWORD Test );
|
||||
BYTE * CompileDelaySlot ( DWORD PC );
|
||||
|
||||
//Self modifying code methods
|
||||
void ClearRecompCode_Virt ( DWORD VirtualAddress, int length, REMOVE_REASON Reason );
|
||||
|
|
|
@ -36,7 +36,8 @@ 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 & 0xFFC) != 0xFFC) {
|
||||
if ((m_CompilePC & 0xFFC) != 0xFFC)
|
||||
{
|
||||
switch (BranchType) {
|
||||
case BranchTypeRs: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC,m_Opcode.rs,0); break;
|
||||
case BranchTypeRsRt: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC,m_Opcode.rs,m_Opcode.rt); break;
|
||||
|
@ -66,7 +67,7 @@ void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc,
|
|||
#endif
|
||||
}
|
||||
} else {
|
||||
EffectDelaySlot = TRUE;
|
||||
EffectDelaySlot = true;
|
||||
}
|
||||
m_Section->m_Jump.JumpPC = m_CompilePC;
|
||||
m_Section->m_Jump.TargetPC = m_CompilePC + ((short)m_Opcode.offset << 2) + 4;
|
||||
|
@ -95,10 +96,6 @@ void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc,
|
|||
m_Section->m_Cont.FallThrough = TRUE;
|
||||
m_Section->m_Jump.FallThrough = FALSE;
|
||||
}
|
||||
if (m_Section->m_Jump.TargetPC == m_Section->m_Cont.TargetPC)
|
||||
{
|
||||
EffectDelaySlot = (m_CompilePC & 0xFFC) == 0xFFC;
|
||||
}
|
||||
|
||||
if (Link) {
|
||||
UnMap_GPR( 31, FALSE);
|
||||
|
@ -106,17 +103,18 @@ void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc,
|
|||
MipsRegState(31) = CRegInfo::STATE_CONST_32;
|
||||
}
|
||||
if (EffectDelaySlot) {
|
||||
m_Section->m_Cont.BranchLabel = m_Section->m_ContinueSection != NULL ? "Continue" : "ExitBlock";
|
||||
m_Section->m_Jump.BranchLabel = m_Section->m_JumpSection != NULL ? "Jump" : "ExitBlock";
|
||||
if ((m_CompilePC & 0xFFC) != 0xFFC)
|
||||
{
|
||||
m_Section->m_Cont.BranchLabel = m_Section->m_ContinueSection != NULL ? "Continue" : "ExitBlock";
|
||||
m_Section->m_Jump.BranchLabel = m_Section->m_JumpSection != NULL ? "Jump" : "ExitBlock";
|
||||
} else {
|
||||
m_Section->m_Cont.BranchLabel = "Continue";
|
||||
m_Section->m_Jump.BranchLabel = "Jump";
|
||||
}
|
||||
if (m_Section->m_Jump.TargetPC != m_Section->m_Cont.TargetPC)
|
||||
{
|
||||
CompareFunc();
|
||||
}
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC) {
|
||||
m_Section->GenerateSectionLinkage();
|
||||
m_NextInstruction = END_BLOCK;
|
||||
return;
|
||||
}
|
||||
if (!m_Section->m_Jump.FallThrough && !m_Section->m_Cont.FallThrough) {
|
||||
if (m_Section->m_Jump.LinkLocation != NULL) {
|
||||
CPU_Message("");
|
||||
|
@ -140,6 +138,55 @@ void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc,
|
|||
m_Section->m_Cont.FallThrough = TRUE;
|
||||
}
|
||||
}
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC)
|
||||
{
|
||||
BYTE * DelayLinkLocation = NULL;
|
||||
if (m_Section->m_Jump.FallThrough)
|
||||
{
|
||||
if (m_Section->m_Jump.LinkLocation != NULL || m_Section->m_Jump.LinkLocation2 != NULL)
|
||||
{
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
}
|
||||
MoveConstToVariable(m_Section->m_Jump.TargetPC,&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation");
|
||||
}
|
||||
else if (m_Section->m_Cont.FallThrough)
|
||||
{
|
||||
if (m_Section->m_Cont.LinkLocation != NULL || m_Section->m_Cont.LinkLocation2 != NULL)
|
||||
{
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
}
|
||||
MoveConstToVariable(m_Section->m_Cont.TargetPC,&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation");
|
||||
}
|
||||
|
||||
if (m_Section->m_Jump.LinkLocation != NULL || m_Section->m_Jump.LinkLocation2 != NULL)
|
||||
{
|
||||
JmpLabel8("DoDelaySlot",0);
|
||||
if (DelayLinkLocation != NULL) { _Notify->BreakPoint(__FILE__,__LINE__); }
|
||||
DelayLinkLocation = (BYTE *)(m_RecompPos - 1);
|
||||
|
||||
CPU_Message(" ");
|
||||
CPU_Message(" %s:",m_Section->m_Jump.BranchLabel.c_str());
|
||||
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");
|
||||
}
|
||||
if (m_Section->m_Cont.LinkLocation != NULL || m_Section->m_Cont.LinkLocation2 != NULL)
|
||||
{
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
}
|
||||
if (DelayLinkLocation)
|
||||
{
|
||||
CPU_Message("");
|
||||
CPU_Message(" DoDelaySlot:");
|
||||
SetJump8(DelayLinkLocation,m_RecompPos);
|
||||
}
|
||||
OverflowDelaySlot();
|
||||
return;
|
||||
}
|
||||
ResetX86Protection();
|
||||
memcpy(&RegBeforeDelay,&m_RegWorkingSet,sizeof(CRegInfo));
|
||||
}
|
||||
|
@ -268,7 +315,8 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link
|
|||
m_NextInstruction = END_BLOCK;
|
||||
} else {
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC) {
|
||||
m_Section->m_Jump.FallThrough = FALSE;
|
||||
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;
|
||||
|
@ -277,8 +325,8 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link
|
|||
m_Section->m_Jump.LinkLocation2 = NULL;
|
||||
}
|
||||
}
|
||||
JmpLabel32("DoDelaySlot",0);
|
||||
m_Section->m_Jump.LinkLocation = (DWORD *)(m_RecompPos - 4);
|
||||
MoveConstToVariable(m_Section->m_Jump.TargetPC,&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation");
|
||||
OverflowDelaySlot();
|
||||
CPU_Message(" ");
|
||||
CPU_Message(" %s:",m_Section->m_Cont.BranchLabel.c_str());
|
||||
if (m_Section->m_Cont.LinkLocation != NULL) {
|
||||
|
@ -290,10 +338,7 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link
|
|||
}
|
||||
}
|
||||
m_Section->CompileExit(m_CompilePC, m_CompilePC + 8,m_Section->m_Cont.RegSet,CExitInfo::Normal,TRUE,NULL);
|
||||
CPU_Message("");
|
||||
CPU_Message(" DoDelaySlot:");
|
||||
m_Section->GenerateSectionLinkage();
|
||||
m_NextInstruction = END_BLOCK;
|
||||
return;
|
||||
} else {
|
||||
m_NextInstruction = DO_DELAY_SLOT;
|
||||
}
|
||||
|
@ -1217,10 +1262,14 @@ void CRecompilerOps::J (void) {
|
|||
m_Section->m_Jump.LinkLocation = NULL;
|
||||
m_Section->m_Jump.LinkLocation2 = NULL;
|
||||
m_NextInstruction = DO_DELAY_SLOT;
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC) {
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC)
|
||||
{
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
#ifdef tofix
|
||||
memcpy(&m_Section->m_Jump.RegSet,&m_RegWorkingSet,sizeof(CRegInfo));
|
||||
m_Section->GenerateSectionLinkage();
|
||||
m_NextInstruction = END_BLOCK;
|
||||
#endif
|
||||
}
|
||||
} else if (m_NextInstruction == DELAY_SLOT_DONE ) {
|
||||
m_Section->m_Jump.RegSet = m_RegWorkingSet;
|
||||
|
@ -1239,7 +1288,13 @@ void CRecompilerOps::JAL (void) {
|
|||
UnMap_GPR( 31, FALSE);
|
||||
MipsRegLo(31) = m_CompilePC + 8;
|
||||
MipsRegState(31) = CRegInfo::STATE_CONST_32;
|
||||
m_Section->m_Jump.TargetPC = (m_CompilePC & 0xF0000000) + (m_Opcode.target << 2);
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC)
|
||||
{
|
||||
MoveConstToVariable((m_CompilePC & 0xF0000000) + (m_Opcode.target << 2),&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation");
|
||||
OverflowDelaySlot();
|
||||
return;
|
||||
}
|
||||
m_Section->m_Jump.TargetPC = (m_CompilePC & 0xF0000000) + (m_Opcode.target << 2);
|
||||
m_Section->m_Jump.JumpPC = m_CompilePC;
|
||||
if (m_Section->m_JumpSection != NULL) {
|
||||
m_Section->m_Jump.BranchLabel.Format("Section_%d",((CCodeSection *)m_Section->m_JumpSection)->m_SectionID);
|
||||
|
@ -1249,14 +1304,7 @@ void CRecompilerOps::JAL (void) {
|
|||
m_Section->m_Jump.FallThrough = TRUE;
|
||||
m_Section->m_Jump.LinkLocation = NULL;
|
||||
m_Section->m_Jump.LinkLocation2 = NULL;
|
||||
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC)
|
||||
{
|
||||
m_Section->GenerateSectionLinkage();
|
||||
m_NextInstruction = END_BLOCK;
|
||||
} else {
|
||||
m_NextInstruction = DO_DELAY_SLOT;
|
||||
}
|
||||
m_NextInstruction = DO_DELAY_SLOT;
|
||||
} else if (m_NextInstruction == DELAY_SLOT_DONE ) {
|
||||
if (m_Section->m_JumpSection)
|
||||
{
|
||||
|
@ -1921,6 +1969,19 @@ void CRecompilerOps::SPECIAL_SRAV (void) {
|
|||
void CRecompilerOps::SPECIAL_JR (void) {
|
||||
if ( m_NextInstruction == NORMAL ) {
|
||||
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC));
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC)
|
||||
{
|
||||
if (IsMapped(m_Opcode.rs)) {
|
||||
MoveX86regToVariable(cMipsRegMapLo(m_Opcode.rs),&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation");
|
||||
m_RegWorkingSet.WriteBackRegisters();
|
||||
} else {
|
||||
m_RegWorkingSet.WriteBackRegisters();
|
||||
MoveX86regToVariable(Map_TempReg(x86_Any,m_Opcode.rs,FALSE),&R4300iOp::m_JumpToLocation,"R4300iOp::m_JumpToLocation");
|
||||
}
|
||||
OverflowDelaySlot();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsConst(m_Opcode.rs)) {
|
||||
m_Section->m_Jump.BranchLabel.Format("0x%08X",cMipsRegLo(m_Opcode.rs));
|
||||
m_Section->m_Jump.TargetPC = cMipsRegLo(m_Opcode.rs);
|
||||
|
@ -1932,8 +1993,11 @@ void CRecompilerOps::SPECIAL_JR (void) {
|
|||
m_Section->m_Cont.LinkLocation = NULL;
|
||||
m_Section->m_Cont.LinkLocation2 = NULL;
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC) {
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
#ifdef tofix
|
||||
m_Section->GenerateSectionLinkage();
|
||||
m_NextInstruction = END_BLOCK;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -1944,16 +2008,6 @@ void CRecompilerOps::SPECIAL_JR (void) {
|
|||
m_Section->m_Cont.LinkLocation = NULL;
|
||||
m_Section->m_Cont.LinkLocation2 = NULL;
|
||||
}
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC) {
|
||||
if (IsMapped(m_Opcode.rs)) {
|
||||
Push(cMipsRegMapLo(m_Opcode.rs));
|
||||
} else {
|
||||
Push(Map_TempReg(x86_Any,m_Opcode.rs,FALSE));
|
||||
}
|
||||
m_Section->GenerateSectionLinkage();
|
||||
m_NextInstruction = END_BLOCK;
|
||||
return;
|
||||
}
|
||||
if (DelaySlotEffectsCompare(m_CompilePC,m_Opcode.rs,0)) {
|
||||
if (IsConst(m_Opcode.rs)) {
|
||||
MoveConstToVariable(cMipsRegLo(m_Opcode.rs),_PROGRAM_COUNTER, "PROGRAM_COUNTER");
|
||||
|
@ -2004,6 +2058,8 @@ void CRecompilerOps::SPECIAL_JALR (void) {
|
|||
MipsRegLo(m_Opcode.rd) = m_CompilePC + 8;
|
||||
MipsRegState(m_Opcode.rd) = CRegInfo::STATE_CONST_32;
|
||||
if ((m_CompilePC & 0xFFC) == 0xFFC) {
|
||||
_Notify->BreakPoint(__FILE__,__LINE__);
|
||||
#ifdef tofix
|
||||
if (IsMapped(m_Opcode.rs)) {
|
||||
Push(cMipsRegMapLo(m_Opcode.rs));
|
||||
} else {
|
||||
|
@ -2011,6 +2067,7 @@ void CRecompilerOps::SPECIAL_JALR (void) {
|
|||
}
|
||||
m_Section->GenerateSectionLinkage();
|
||||
m_NextInstruction = END_BLOCK;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
m_NextInstruction = DO_DELAY_SLOT;
|
||||
|
@ -5043,20 +5100,27 @@ void CRecompilerOps::ExitCodeBlock ( void )
|
|||
Ret();
|
||||
}
|
||||
|
||||
void CRecompilerOps::UpdateSyncCPU ( CRegInfo & RegSet, DWORD Cycles )
|
||||
{
|
||||
if (!_SyncSystem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteX86Comment("Updating Sync CPU");
|
||||
BeforeCallDirect(RegSet);
|
||||
PushImm32(stdstr_f("%d",Cycles).c_str(),Cycles);
|
||||
PushImm32("_SyncSystem",(DWORD)_SyncSystem);
|
||||
MoveConstToX86reg((DWORD)_System,x86_ECX);
|
||||
Call_Direct(AddressOf(&CN64System::UpdateSyncCPU),"CN64System::UpdateSyncCPU");
|
||||
AfterCallDirect(RegSet);
|
||||
}
|
||||
|
||||
void CRecompilerOps::UpdateCounters ( CRegInfo & RegSet, bool CheckTimer, bool ClearValues )
|
||||
{
|
||||
if (RegSet.GetBlockCycleCount() != 0)
|
||||
{
|
||||
if (_SyncSystem) {
|
||||
|
||||
WriteX86Comment("Updating Sync CPU");
|
||||
BeforeCallDirect(RegSet);
|
||||
PushImm32(stdstr_f("%d",RegSet.GetBlockCycleCount()).c_str(),RegSet.GetBlockCycleCount());
|
||||
PushImm32("_SyncSystem",(DWORD)_SyncSystem);
|
||||
MoveConstToX86reg((DWORD)_System,x86_ECX);
|
||||
Call_Direct(AddressOf(&CN64System::UpdateSyncCPU),"CN64System::UpdateSyncCPU");
|
||||
AfterCallDirect(RegSet);
|
||||
}
|
||||
UpdateSyncCPU(RegSet,RegSet.GetBlockCycleCount());
|
||||
WriteX86Comment("Update Counter");
|
||||
SubConstFromVariable(RegSet.GetBlockCycleCount(),_NextTimer,"_NextTimer"); // updates compare flag
|
||||
if (ClearValues)
|
||||
|
@ -5102,3 +5166,21 @@ void CRecompilerOps::CompileSystemCheck (DWORD TargetPC, CRegInfo RegSet)
|
|||
SetJump32(Jump,(DWORD *)m_RecompPos);
|
||||
}
|
||||
|
||||
void CRecompilerOps::OverflowDelaySlot (void)
|
||||
{
|
||||
m_RegWorkingSet.WriteBackRegisters();
|
||||
UpdateCounters(m_RegWorkingSet,false,true);
|
||||
MoveConstToVariable(CompilePC() + 4,_PROGRAM_COUNTER,"PROGRAM_COUNTER");
|
||||
if (_SyncSystem) { Call_Direct(SyncSystem, "SyncSystem"); }
|
||||
MoveConstToVariable(JUMP,&R4300iOp::m_NextInstruction,"R4300iOp::m_NextInstruction");
|
||||
PushImm32("CountPerOp()",CountPerOp());
|
||||
Call_Direct(CInterpreterCPU::ExecuteOps, "CInterpreterCPU::ExecuteOps");
|
||||
AddConstToX86Reg(x86_ESP,4);
|
||||
if (_SyncSystem)
|
||||
{
|
||||
UpdateSyncCPU(m_RegWorkingSet,g_CountPerOp);
|
||||
Call_Direct(SyncSystem, "SyncSystem");
|
||||
}
|
||||
ExitCodeBlock();
|
||||
m_NextInstruction = END_BLOCK;
|
||||
}
|
|
@ -191,9 +191,11 @@ protected:
|
|||
static void ExitCodeBlock ( void );
|
||||
static void CompileReadTLBMiss (int AddressReg, int LookUpReg );
|
||||
static void CompileWriteTLBMiss (int AddressReg, int LookUpReg );
|
||||
static void UpdateSyncCPU (CRegInfo & RegSet, DWORD Cycles);
|
||||
static void UpdateCounters (CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false );
|
||||
static void CompileSystemCheck ( DWORD TargetPC, CRegInfo RegSet );
|
||||
static void ChangeDefaultRoundingModel ( void );
|
||||
static void OverflowDelaySlot ( void );
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue