Initial refractoring of ABL

This commit is contained in:
zilmar 2012-10-14 12:05:52 +11:00
parent 47f184d201
commit afedaf38d6
20 changed files with 2132 additions and 1199 deletions

View File

@ -47,6 +47,7 @@ class CNotification;
//Recompiler
#include "N64 System/Recompiler/Recompiler Memory.h"
#include "N64 System/Recompiler/Reg Info.h"
#include "N64 System/Recompiler/Loop Analysis.h"
#include "N64 System/Recompiler/Recompiler Ops.h"
#include "N64 System/Mips/Memory Virtual Mem.h" //needs to inherit Recompiler ops
#include "N64 System/Recompiler/Exit Info.h"

View File

@ -461,7 +461,7 @@ protected:
class CRegisters:
protected CSystemRegisters,
protected CN64SystemSettings,
protected CGameSettings,
public CP0registers,
public Rdram_InterfaceReg,
public Mips_InterfaceReg,

View File

@ -6,9 +6,16 @@ CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos) :
m_VAddrLast(VAddrEnter),
m_CompiledLocation(RecompPos),
m_NoOfSections(1),
m_EnterSection(this, VAddrEnter, 1),
m_Test(1)
m_Test(1),
m_EnterSection(new CCodeSection(this, VAddrEnter, 1, false))
{
if (m_EnterSection)
{
m_EnterSection->AddParent(NULL);
m_Sections.push_back(m_EnterSection);
}
if (_TransVaddr->VAddrToRealAddr(VAddrEnter,*(reinterpret_cast<void **>(&m_MemLocation[0]))))
{
m_MemLocation[1] = m_MemLocation[0] + 1;
@ -21,13 +28,341 @@ CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos) :
AnalyseBlock();
}
bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSection, DWORD TargetPC, bool LinkAllowed, DWORD CurrentPC )
{
if (Section != NULL)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (TargetPC > ((CurrentPC + 0x1000) & 0xFFFFF000))
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (LinkAllowed)
{
if (Section != NULL)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
SectionMap::const_iterator itr = m_SectionMap.find(TargetPC);
if (itr != m_SectionMap.end())
{
Section = itr->second;
Section->AddParent(CurrentSection);
}
}
if (Section == NULL)
{
Section = new CCodeSection(this,TargetPC,m_Sections.size() + 1,LinkAllowed);
if (Section == NULL)
{
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
m_Sections.push_back(Section);
if (LinkAllowed)
{
m_SectionMap.insert(SectionMap::value_type(TargetPC,Section));
}
Section->AddParent(CurrentSection);
if (TargetPC < CurrentPC)
{
if (TargetPC < m_EnterSection->m_EnterPC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
CCodeSection * SplitSection = m_EnterSection;
for (SectionMap::const_iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++)
{
if (itr->first >= TargetPC)
{
break;
}
SplitSection = itr->second;
}
CCodeSection * BaseSection = Section;
BaseSection->SetJumpAddress(SplitSection->m_Jump.JumpPC, SplitSection->m_Jump.TargetPC);
BaseSection->m_JumpSection = SplitSection->m_JumpSection;
BaseSection->SetContinueAddress(SplitSection->m_Cont.JumpPC,SplitSection->m_Cont.TargetPC);
BaseSection->m_ContinueSection = SplitSection->m_ContinueSection;
BaseSection->m_JumpSection->SwitchParent(SplitSection,BaseSection);
BaseSection->m_ContinueSection->SwitchParent(SplitSection,BaseSection);
BaseSection->AddParent(SplitSection);
SplitSection->m_JumpSection = NULL;
SplitSection->m_ContinueSection = BaseSection;
SplitSection->SetContinueAddress(TargetPC - 4, TargetPC);
SplitSection->SetJumpAddress((DWORD)-1,(DWORD)-1);
}
}
return true;
}
bool CCodeBlock::CreateBlockLinkage ( CCodeSection * EnterSection )
{
CCodeSection * CurrentSection = EnterSection;
for (DWORD TestPC = EnterSection->m_EnterPC, EndPC = ((EnterSection->m_EnterPC + 0x1000) & 0xFFFFF000); TestPC < EndPC; TestPC += 4)
{
{
SectionMap::const_iterator itr = m_SectionMap.find(TestPC);
if (itr != m_SectionMap.end() && CurrentSection != itr->second)
{
if (CurrentSection->m_ContinueSection != NULL &&
CurrentSection->m_ContinueSection != itr->second)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (CurrentSection->m_ContinueSection == NULL)
{
SetSection(CurrentSection->m_ContinueSection, CurrentSection, TestPC,true,TestPC);
CurrentSection->SetContinueAddress(TestPC - 4, TestPC);
}
CurrentSection = itr->second;
}
}
bool LikelyBranch, EndBlock, IncludeDelaySlot;
DWORD TargetPC, ContinuePC;
if (!AnalyzeInstruction(TestPC, TargetPC, ContinuePC, LikelyBranch, IncludeDelaySlot, EndBlock))
{
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
if (TargetPC == (DWORD)-1 && !EndBlock)
{
continue;
}
if (EndBlock)
{
CurrentSection->m_EndSection = true;
// find other sections that need compiling
break;
}
if (ContinuePC != (DWORD)-1)
{
CurrentSection->SetContinueAddress(TestPC, ContinuePC);
SetSection(CurrentSection->m_ContinueSection, CurrentSection, ContinuePC,true,TestPC);
}
if (LikelyBranch)
{
CurrentSection->SetJumpAddress(TestPC, TestPC + 4);
if (SetSection(CurrentSection->m_JumpSection, CurrentSection, TestPC + 4,false,TestPC))
{
CCodeSection * JumpSection = CurrentSection->m_JumpSection;
JumpSection->SetJumpAddress(TestPC, TargetPC);
JumpSection->SetDelaySlot();
SetSection(JumpSection->m_JumpSection,CurrentSection->m_JumpSection,TargetPC,true,TestPC);
}
}
else if (TargetPC != ((DWORD)-1))
{
CurrentSection->SetJumpAddress(TestPC, TargetPC);
SetSection(CurrentSection->m_JumpSection, CurrentSection, TargetPC,true,TestPC);
}
TestPC += IncludeDelaySlot ? 8 : 4;
//retest current section
CCodeSection * NewSection = m_EnterSection;
for (SectionMap::const_iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++)
{
if (itr->first > TestPC)
{
break;
}
NewSection = itr->second;
}
if (CurrentSection == NewSection)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
CurrentSection = NewSection;
TestPC -= 4;
}
for (SectionList::iterator itr = m_Sections.begin(); itr != m_Sections.end(); itr++)
{
CCodeSection * Section = *itr;
if (Section->m_JumpSection != NULL ||
Section->m_ContinueSection != NULL ||
Section->m_EndSection)
{
continue;
}
if (!CreateBlockLinkage(Section)) { return false; }
break;
}
return true;
}
void CCodeBlock::DetermineLoops ( void )
{
for (SectionMap::iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++)
{
CCodeSection * Section = itr->second;
DWORD Test = NextTest();
Section->DetermineLoop(Test,Test,Section->m_SectionID);
}
}
void CCodeBlock::LogSectionInfo ( void )
{
for (SectionList::iterator itr = m_Sections.begin(); itr != m_Sections.end(); itr++)
{
CCodeSection * Section = *itr;
Section->DisplaySectionInformation();
}
}
bool CCodeBlock::AnalyseBlock ( void )
{
if (bLinkBlocks())
{
if (!m_EnterSection.CreateSectionLinkage ()) { return false; }
m_EnterSection.DetermineLoop(NextTest(),NextTest(), m_EnterSection.m_SectionID);
while (m_EnterSection.FixConstants(NextTest())) {}
if (!bLinkBlocks()) { return true; }
if (!CreateBlockLinkage(m_EnterSection)) { return false; }
DetermineLoops();
//LogSectionInfo();
return true;
}
bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & ContinuePC, bool & LikelyBranch, bool & IncludeDelaySlot, bool & EndBlock )
{
TargetPC = (DWORD)-1;
ContinuePC = (DWORD)-1;
LikelyBranch = false;
IncludeDelaySlot = false;
EndBlock = false;
OPCODE Command;
if (!_MMU->LW_VAddr(PC, Command.Hex)) {
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
#ifdef _DEBUG
char * Name = R4300iOpcodeName(Command.Hex,PC);
Name = Name;
#endif
switch (Command.op)
{
case R4300i_SPECIAL:
switch (Command.funct)
{
case R4300i_SPECIAL_SLL: case R4300i_SPECIAL_SRL: case R4300i_SPECIAL_SRA:
case R4300i_SPECIAL_SLLV: case R4300i_SPECIAL_SRLV: case R4300i_SPECIAL_SRAV:
case R4300i_SPECIAL_MFHI: case R4300i_SPECIAL_MTHI: case R4300i_SPECIAL_MFLO:
case R4300i_SPECIAL_MTLO: case R4300i_SPECIAL_DSLLV: case R4300i_SPECIAL_DSRLV:
case R4300i_SPECIAL_DSRAV: case R4300i_SPECIAL_ADD: case R4300i_SPECIAL_ADDU:
case R4300i_SPECIAL_SUB: case R4300i_SPECIAL_SUBU: case R4300i_SPECIAL_AND:
case R4300i_SPECIAL_OR: case R4300i_SPECIAL_XOR: case R4300i_SPECIAL_NOR:
case R4300i_SPECIAL_SLT: case R4300i_SPECIAL_SLTU: case R4300i_SPECIAL_DADD:
case R4300i_SPECIAL_DADDU: case R4300i_SPECIAL_DSUB: case R4300i_SPECIAL_DSUBU:
case R4300i_SPECIAL_DSLL: case R4300i_SPECIAL_DSRL: case R4300i_SPECIAL_DSRA:
case R4300i_SPECIAL_DSLL32: case R4300i_SPECIAL_DSRL32: case R4300i_SPECIAL_DSRA32:
case R4300i_SPECIAL_MULT: case R4300i_SPECIAL_MULTU: case R4300i_SPECIAL_DIV:
case R4300i_SPECIAL_DIVU: case R4300i_SPECIAL_DMULT: case R4300i_SPECIAL_DMULTU:
case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIVU:
break;
case R4300i_SPECIAL_JR:
EndBlock = true;
IncludeDelaySlot = true;
break;
default:
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
break;
case R4300i_REGIMM:
switch (Command.rt) {
case R4300i_REGIMM_BGEZAL:
TargetPC = PC + ((short)Command.offset << 2) + 4;
IncludeDelaySlot = true;
if (Command.rs != 0)
{
ContinuePC = PC + 8;
}
if (TargetPC == PC)
{
if (Command.rs == 0)
{
TargetPC = (DWORD)-1;
EndBlock = true;
} else {
//if delay slot effects compare;
_Notify->BreakPoint(__FILE__,__LINE__);
}
}
break;
default:
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
break;
case R4300i_BEQ:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (Command.rs != 0 || Command.rt != 0)
{
ContinuePC = PC + 8;
}
IncludeDelaySlot = true;
break;
case R4300i_BNE:
TargetPC = PC + ((short)Command.offset << 2) + 4;
ContinuePC = PC + 8;
IncludeDelaySlot = true;
break;
case R4300i_CP0:
switch (Command.rs)
{
case R4300i_COP0_MT: case R4300i_COP0_MF:
break;
default:
if ( (Command.rs & 0x10 ) != 0 )
{
switch( Command.funct ) {
case R4300i_COP0_CO_TLBR: case R4300i_COP0_CO_TLBWI:
case R4300i_COP0_CO_TLBWR: case R4300i_COP0_CO_TLBP:
break;
default:
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
} else {
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
break;
}
break;
case R4300i_CP1:
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
case R4300i_ANDI: case R4300i_ORI: case R4300i_XORI: case R4300i_LUI:
case R4300i_ADDI: case R4300i_ADDIU: case R4300i_SLTI: case R4300i_SLTIU:
case R4300i_DADDI: case R4300i_DADDIU: case R4300i_LB: case R4300i_LH:
case R4300i_LW: case R4300i_LWL: case R4300i_LWR: case R4300i_LDL:
case R4300i_LDR: case R4300i_LBU: case R4300i_LHU: case R4300i_LD:
case R4300i_LWC1: case R4300i_LDC1: case R4300i_CACHE: case R4300i_SB:
case R4300i_SH: case R4300i_SW: case R4300i_SWR: case R4300i_SWL:
case R4300i_SWC1: case R4300i_SDC1: case R4300i_SD:
break;
case R4300i_BNEL:
TargetPC = PC + ((short)Command.offset << 2) + 4;
ContinuePC = PC + 8;
LikelyBranch = true;
IncludeDelaySlot = true;
break;
default:
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
return true;
}
@ -53,9 +388,9 @@ bool CCodeBlock::Compile()
}
if (bLinkBlocks()) {
while (m_EnterSection.GenerateX86Code(NextTest()));
while (m_EnterSection->GenerateX86Code(NextTest()));
} else {
if (!m_EnterSection.GenerateX86Code(NextTest()))
if (!m_EnterSection->GenerateX86Code(NextTest()))
{
return false;
}
@ -78,12 +413,11 @@ void CCodeBlock::CompileExitCode ( void )
CPU_Message(" $Exit_%d",ExitIter->ID);
SetJump32(ExitIter->JumpLoc,(DWORD *)m_RecompPos);
m_NextInstruction = ExitIter->NextInstruction;
m_EnterSection.CompileExit((DWORD)-1, ExitIter->TargetPC,ExitIter->ExitRegSet,ExitIter->reason,true,NULL);
m_EnterSection->CompileExit((DWORD)-1, ExitIter->TargetPC,ExitIter->ExitRegSet,ExitIter->reason,true,NULL);
}
}
DWORD CCodeBlock::NextTest ( void )
{
m_Test += 1;
return m_Test;
return InterlockedIncrement(&m_Test);
}

View File

@ -11,7 +11,7 @@ public:
inline DWORD VAddrLast ( void ) const { return m_VAddrLast; }
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 const CCodeSection & EnterSection ( void ) const { return *m_EnterSection; }
inline const MD5Digest & Hash ( void ) const { return m_Hash; }
inline void SetVAddrFirst ( DWORD VAddr ) { m_VAddrFirst = VAddr; }
@ -19,8 +19,8 @@ public:
inline void IncSectionCount ( void ) { m_NoOfSections += 1; }
CCodeSection * ExistingSection ( DWORD Addr ) { return m_EnterSection.ExistingSection(Addr,NextTest()); }
bool SectionAccessible ( DWORD m_SectionID ) { return m_EnterSection.SectionAccessible(m_SectionID,NextTest()); }
CCodeSection * ExistingSection ( DWORD Addr ) { return m_EnterSection->ExistingSection(Addr,NextTest()); }
bool SectionAccessible ( DWORD m_SectionID ) { return m_EnterSection->SectionAccessible(m_SectionID,NextTest()); }
inline QWORD MemContents(int i) const { return m_MemContents[i]; }
inline QWORD * MemLocation(int i) const { return m_MemLocation[i]; }
@ -32,13 +32,26 @@ private:
bool AnalyseBlock ( void );
void CompileExitCode ( void );
bool CreateBlockLinkage ( CCodeSection * EnterSection ) ;
void DetermineLoops ( void ) ;
void LogSectionInfo ( void ) ;
bool SetSection ( CCodeSection * & Section, CCodeSection * CurrentSection, DWORD TargetPC, bool LinkAllowed, DWORD CurrentPC );
bool SetJumpInfo ( CCodeSection * & Section, DWORD TargetPC, DWORD CurrentPC );
bool AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & ContinuePC, bool & LikelyBranch, bool & IncludeDelaySlot, bool & EndBlock );
DWORD m_VAddrEnter;
DWORD m_VAddrFirst; // the address of the first opcode in the block
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
CCodeSection m_EnterSection;
DWORD m_Test;
typedef std::map<DWORD,CCodeSection *> SectionMap;
typedef std::list<CCodeSection *> SectionList;
SectionMap m_SectionMap;
SectionList m_Sections;
CCodeSection * m_EnterSection;
long m_Test;
MD5Digest m_Hash;
QWORD m_MemContents[2];
QWORD * m_MemLocation[2];

File diff suppressed because it is too large Load Diff

View File

@ -5,12 +5,15 @@ class CCodeBlock;
class CCodeSection :
private CRecompilerOps
{
public:
typedef std::list<CCodeSection *> SECTION_LIST;
public:
CCodeSection( CCodeBlock * CodeBlock, DWORD EnterPC, DWORD ID);
CCodeSection( CCodeBlock * CodeBlock, DWORD EnterPC, DWORD ID, bool LinkAllowed);
~CCodeSection( void );
void SetDelaySlot ( void );
void SetJumpAddress ( DWORD JumpPC, DWORD TargetPC );
void SetContinueAddress ( DWORD JumpPC, DWORD TargetPC );
void CompileCop1Test ( void );
bool CreateSectionLinkage ( void );
bool GenerateX86Code ( DWORD Test );
@ -22,6 +25,8 @@ public:
bool SectionAccessible ( DWORD SectionId, DWORD Test );
bool DisplaySectionInformation ( DWORD ID, DWORD Test );
void DisplaySectionInformation ( void );
void AddParent ( CCodeSection * Parent );
void SwitchParent ( CCodeSection * OldParent, CCodeSection * NewParent );
/* Block Connection info */
SECTION_LIST m_ParentSection;
@ -30,11 +35,13 @@ public:
const DWORD m_SectionID;
CCodeSection * m_ContinueSection;
CCodeSection * m_JumpSection;
bool m_EndSection; // if this section does not link
bool m_LinkAllowed; // are other sections allowed to find block to link to it
DWORD m_Test;
DWORD m_Test2;
BYTE * m_CompiledLocation;
bool m_InLoop;
bool m_DelaySlot;
/* Register Info */
CRegInfo m_RegEnter;
@ -44,14 +51,13 @@ public:
CJumpInfo m_Cont;
private:
void AddParent ( CCodeSection * Parent );
void UnlinkParent ( CCodeSection * Parent, bool ContinueSection );
void InheritConstants ( void );
bool FillSectionInfo ( STEP_TYPE StartStepType );
void TestRegConstantStates ( CRegInfo & Base, CRegInfo & Reg );
void SyncRegState ( const CRegInfo & SyncTo );
bool IsAllParentLoops ( CCodeSection * Parent, bool IgnoreIfCompiled, DWORD Test );
bool ParentContinue ( void );
bool InheritParentInfo ( void );
void UnlinkParent ( CCodeSection * Parent, bool ContinueSection );
void InheritConstants ( void );
void TestRegConstantStates ( CRegInfo & Base, CRegInfo & Reg );
void SyncRegState ( const CRegInfo & SyncTo );
bool IsAllParentLoops ( CCodeSection * Parent, bool IgnoreIfCompiled, DWORD Test );
bool ParentContinue ( void );
bool InheritParentInfo ( void );
bool SetupRegisterForLoop ( void );
};

View File

@ -10,6 +10,6 @@ public:
DWORD * LinkLocation2;
BOOL FallThrough;
BOOL PermLoop;
BOOL DoneDelaySlot;
BOOL DoneDelaySlot; //maybe deletable
CRegInfo RegSet;
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
#pragma once
class CCodeSection;
class CCodeBlock;
class LoopAnalysis
{
public:
LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section);
bool SetupRegisterForLoop ( void );
private:
LoopAnalysis(void); // Disable default constructor
LoopAnalysis(const LoopAnalysis&); // Disable copy constructor
LoopAnalysis& operator=(const LoopAnalysis&); // Disable assignment
bool CheckLoopRegisterUsage ( CCodeSection * Section, DWORD Test, DWORD Test2 );
/********************** R4300i OpCodes: Special **********************/
void SPECIAL_SLL ( void );
void SPECIAL_SRL ( void );
void SPECIAL_SRA ( void );
void SPECIAL_SLLV ( void );
void SPECIAL_SRLV ( void );
void SPECIAL_SRAV ( void );
void SPECIAL_JR ( void );
void SPECIAL_JALR ( void );
void SPECIAL_SYSCALL ( void );
void SPECIAL_BREAK ( void );
void SPECIAL_MFHI ( void );
void SPECIAL_MTHI ( void );
void SPECIAL_MFLO ( void );
void SPECIAL_MTLO ( void );
void SPECIAL_DSLLV ( void );
void SPECIAL_DSRLV ( void );
void SPECIAL_DSRAV ( void );
void SPECIAL_ADD ( void );
void SPECIAL_ADDU ( void );
void SPECIAL_SUB ( void );
void SPECIAL_SUBU ( void );
void SPECIAL_AND ( void );
void SPECIAL_OR ( void );
void SPECIAL_XOR ( void );
void SPECIAL_NOR ( void );
void SPECIAL_SLT ( void );
void SPECIAL_SLTU ( void );
void SPECIAL_DADD ( void );
void SPECIAL_DADDU ( void );
void SPECIAL_DSUB ( void );
void SPECIAL_DSUBU ( void );
void SPECIAL_DSLL ( void );
void SPECIAL_DSRL ( void );
void SPECIAL_DSRA ( void );
void SPECIAL_DSLL32 ( void );
void SPECIAL_DSRL32 ( void );
void SPECIAL_DSRA32 ( void );
CCodeSection * m_EnterSection;
CCodeBlock * m_BlockInfo;
DWORD m_PC;
CRegInfo m_Reg;
STEP_TYPE m_NextInstruction;
OPCODE m_Command;
};

View File

@ -196,7 +196,7 @@ void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc,
return;
}
ResetX86Protection();
memcpy(&RegBeforeDelay,&m_RegWorkingSet,sizeof(CRegInfo));
RegBeforeDelay = m_RegWorkingSet;
}
m_NextInstruction = DO_DELAY_SLOT;
} else if (m_NextInstruction == DELAY_SLOT_DONE ) {
@ -285,75 +285,89 @@ void CRecompilerOps::Compile_BranchLikely (BranchFunction CompareFunc, BOOL Link
if ( m_NextInstruction == NORMAL ) {
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,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";
if (!bLinkBlocks())
{
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;
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;
m_Section->m_Jump.LinkLocation2 = NULL;
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";
}
m_Section->m_Cont.FallThrough = FALSE;
m_Section->m_Cont.LinkLocation = NULL;
m_Section->m_Cont.LinkLocation2 = NULL;
if (Link) {
if (Link)
{
UnMap_GPR( 31, FALSE);
MipsRegLo(31) = m_CompilePC + 8;
m_RegWorkingSet.SetMipsRegState(31,CRegInfo::STATE_CONST_32);
}
CompareFunc();
ResetX86Protection();
m_Section->m_Cont.RegSet = m_RegWorkingSet;
if (m_Section->m_Cont.FallThrough) {
if (m_Section->m_Jump.LinkLocation != NULL) {
#ifndef EXTERNAL_RELEASE
_Notify->DisplayError("WTF .. problem with CRecompilerOps::BranchLikely");
#endif
}
if (bLinkBlocks())
{
m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->m_Cont.RegSet = m_RegWorkingSet;
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;
}
m_Section->m_Cont.RegSet = m_RegWorkingSet;
if (m_Section->m_Cont.FallThrough)
{
if (m_Section->m_Jump.LinkLocation != NULL)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
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;
m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK;
} else {
m_NextInstruction = DO_DELAY_SLOT;
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 ) {
ResetX86Protection();
memcpy(&m_Section->m_Jump.RegSet,&m_RegWorkingSet,sizeof(CRegInfo));
m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK;
} else {
@ -1383,15 +1397,10 @@ void CRecompilerOps::SLTIU (void) {
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC));
if (m_Opcode.rt == 0) { return; }
if (IsConst(m_Opcode.rs)) {
DWORD Result;
if (Is64Bit(m_Opcode.rs)) {
__int64 Immediate = (__int64)((short)m_Opcode.immediate);
Result = MipsReg(m_Opcode.rs) < ((unsigned)(Immediate))?1:0;
} else if (Is32Bit(m_Opcode.rs)) {
Result = cMipsRegLo(m_Opcode.rs) < ((unsigned)((short)m_Opcode.immediate))?1:0;
}
if (IsConst(m_Opcode.rs))
{
DWORD Result = Is64Bit(m_Opcode.rs) ? MipsReg(m_Opcode.rs) < ((unsigned)((__int64)((short)m_Opcode.immediate)))?1:0 :
cMipsRegLo(m_Opcode.rs) < ((unsigned)((short)m_Opcode.immediate))?1:0;
UnMap_GPR(m_Opcode.rt, FALSE);
m_RegWorkingSet.SetMipsRegState(m_Opcode.rt,CRegInfo::STATE_CONST_32);
MipsRegLo(m_Opcode.rt) = Result;
@ -2069,7 +2078,7 @@ void CRecompilerOps::SPECIAL_JALR (void)
m_NextInstruction = DO_DELAY_SLOT;
} else if (m_NextInstruction == DELAY_SLOT_DONE ) {
if (IsConst(m_Opcode.rs)) {
memcpy(&m_Section->m_Jump.RegSet,&m_RegWorkingSet,sizeof(CRegInfo));
m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->m_Jump.BranchLabel.Format("0x%08X",cMipsRegLo(m_Opcode.rs));
m_Section->m_Jump.TargetPC = cMipsRegLo(m_Opcode.rs);
m_Section->m_Jump.FallThrough = TRUE;
@ -5132,7 +5141,7 @@ void CRecompilerOps::UpdateCounters ( CRegInfo & RegSet, bool CheckTimer, bool C
}
}
void CRecompilerOps::CompileSystemCheck (DWORD TargetPC, CRegInfo RegSet)
void CRecompilerOps::CompileSystemCheck (DWORD TargetPC, const CRegInfo & RegSet)
{
CompConstToVariable(0,(void *)&_SystemEvents->DoSomething(),"_SystemEvents->DoSomething()");
JeLabel32("Continue_From_Interrupt_Test",0);
@ -5142,7 +5151,9 @@ void CRecompilerOps::CompileSystemCheck (DWORD TargetPC, CRegInfo RegSet)
MoveConstToVariable(TargetPC,&_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER");
}
RegSet.WriteBackRegisters();
CRegInfo RegSetCopy(RegSet);
RegSetCopy.WriteBackRegisters();
MoveConstToX86reg((DWORD)_SystemEvents,x86_ECX);
Call_Direct(AddressOf(&CSystemEvents::ExecuteEvents),"CSystemEvents::ExecuteEvents");
if (_SyncSystem) {

View File

@ -193,7 +193,7 @@ protected:
static void CompileWriteTLBMiss (x86Reg AddressReg, x86Reg 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 CompileSystemCheck ( DWORD TargetPC, const CRegInfo & RegSet );
static void ChangeDefaultRoundingModel ( void );
static void OverflowDelaySlot ( BOOL TestTimer );

View File

@ -4,39 +4,123 @@ unsigned int CRegInfo::m_fpuControl = 0;
char *Format_Name[] = {"Unknown","dword","qword","float","double"};
void CRegInfo::Initilize ( bool b32bitCore )
CRegInfo::CRegInfo ( void ) :
m_CycleCount(0),
m_Stack_TopPos(0),
m_Fpu_Used(false),
m_RoundingModel(RoundUnknown)
{
m_MIPS_RegState[0] = STATE_CONST_32;
m_MIPS_RegVal[0].DW = 0;
m_RegMapLo[0] = x86_Unknown;
m_RegMapHi[0] = x86_Unknown;
for (int i = 1; i < 32; i++ )
{
m_MIPS_RegState[i] = STATE_UNKNOWN;
m_MIPS_RegVal[i].DW = 0;
m_RegMapLo[i] = x86_Unknown;
m_RegMapHi[i] = x86_Unknown;
}
for (int i = 0, n = sizeof(m_x86reg_MappedTo) / sizeof(m_x86reg_MappedTo[0]); i < n; i++ )
{
m_x86reg_MappedTo[i] = NotMapped;
m_x86reg_Protected[i] = false;
m_x86reg_MapOrder[i] = 0;
}
for (int i = 0, n = sizeof(x86fpu_MappedTo) / sizeof(x86fpu_MappedTo[0]); i < n; i++ )
{
x86fpu_MappedTo[i] = -1;
x86fpu_State[i] = FPU_Unknown;
x86fpu_StateChanged[i] = false;
x86fpu_RoundingModel[i] = RoundDefault;
}
}
CRegInfo::CRegInfo(const CRegInfo& rhs)
{
*this = rhs;
}
CRegInfo::~CRegInfo()
{
}
CRegInfo& CRegInfo::operator=(const CRegInfo& right)
{
m_CycleCount = right.m_CycleCount;
m_Stack_TopPos = right.m_Stack_TopPos;
m_Fpu_Used = right.m_Fpu_Used;
m_RoundingModel = right.m_RoundingModel;
memcpy(&m_MIPS_RegState,&right.m_MIPS_RegState,sizeof(m_MIPS_RegState));
memcpy(&m_MIPS_RegVal,&right.m_MIPS_RegVal,sizeof(m_MIPS_RegVal));
memcpy(&m_RegMapLo,&right.m_RegMapLo,sizeof(m_RegMapLo));
memcpy(&m_RegMapHi,&right.m_RegMapHi,sizeof(m_RegMapHi));
memcpy(&m_x86reg_MappedTo,&right.m_x86reg_MappedTo,sizeof(m_x86reg_MappedTo));
memcpy(&m_x86reg_Protected,&right.m_x86reg_Protected,sizeof(m_x86reg_Protected));
memcpy(&m_x86reg_MapOrder,&right.m_x86reg_MapOrder,sizeof(m_x86reg_MapOrder));
memcpy(&x86fpu_MappedTo,&right.x86fpu_MappedTo,sizeof(x86fpu_MappedTo));
memcpy(&x86fpu_State,&right.x86fpu_State,sizeof(x86fpu_State));
memcpy(&x86fpu_StateChanged,&right.x86fpu_StateChanged,sizeof(x86fpu_StateChanged));
memcpy(&x86fpu_RoundingModel,&right.x86fpu_RoundingModel,sizeof(x86fpu_RoundingModel));
#ifdef _DEBUG
if (*this != right)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
#endif
return *this;
}
bool CRegInfo::operator==(const CRegInfo& right) const
{
int count;
m_b32bitCore = b32bitCore;
MIPS_RegState[0] = STATE_CONST_32;
MIPS_RegVal[0].DW = 0;
RegMapLo[0] = x86_Unknown;
RegMapHi[0] = x86_Unknown;
for (count = 1; count < 32; count ++ ) {
MIPS_RegState[count] = STATE_UNKNOWN;
MIPS_RegVal[count].DW = 0;
RegMapLo[count] = x86_Unknown;
RegMapHi[count] = x86_Unknown;
for (count = 0; count < 32; count ++ ) {
if (m_MIPS_RegState[count] != right.m_MIPS_RegState[count])
{
return false;
}
if (m_MIPS_RegState[count] == STATE_UNKNOWN)
{
continue;
}
if (m_MIPS_RegVal[count].DW != right.m_MIPS_RegVal[count].DW)
{
return false;
}
}
for (count = 0; count < 10; count ++ ) {
x86reg_MappedTo[count] = NotMapped;
x86reg_Protected[count] = false;
x86reg_MapOrder[count] = 0;
if (m_x86reg_MappedTo[count] != right.m_x86reg_MappedTo[count]) { return false; }
if (m_x86reg_Protected[count] != right.m_x86reg_Protected[count]) { return false; }
if (m_x86reg_MapOrder[count] != right.m_x86reg_MapOrder[count]) { return false; }
}
m_CycleCount = 0;
if (m_CycleCount != right.m_CycleCount) { return false; }
if (m_Stack_TopPos != right.m_Stack_TopPos) { return false; }
Stack_TopPos = 0;
for (count = 0; count < 8; count ++ ) {
x86fpu_MappedTo[count] = -1;
x86fpu_State[count] = FPU_Unknown;
x86fpu_StateChanged[count] = false;
x86fpu_RoundingModel[count] = RoundDefault;
if (x86fpu_MappedTo[count] != right.x86fpu_MappedTo[count]) { return false; }
if (x86fpu_State[count] != right.x86fpu_State[count]) { return false; }
if (x86fpu_RoundingModel[count] != right.x86fpu_RoundingModel[count]) { return false; }
}
Fpu_Used = false;
m_RoundingModel = RoundUnknown;
if (m_Fpu_Used != right.m_Fpu_Used) { return false; }
if (GetRoundingModel() != right.GetRoundingModel()) { return false; }
return true;
}
bool CRegInfo::operator!=(const CRegInfo& right) const
{
return !(right == *this);
}
CRegInfo::REG_STATE CRegInfo::ConstantsType (__int64 Value)
{
if (((Value >> 32) == -1) && ((Value & 0x80000000) != 0)) { return STATE_CONST_32; }
if (((Value >> 32) == 0) && ((Value & 0x80000000) == 0)) { return STATE_CONST_32; }
return STATE_CONST_64;
}
void CRegInfo::FixRoundModel(FPU_ROUND RoundMethod )
@ -939,7 +1023,7 @@ void CRegInfo::UnMap_GPR (DWORD Reg, bool WriteBackValue)
MoveX86regToVariable(MipsRegMapHi(Reg),&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
SetMipsRegMapHi(Reg,x86_Unknown);
} else {
if (!m_b32bitCore) {
if (!b32BitCore()) {
if (IsSigned(Reg)) {
ShiftRightSignImmed(MipsRegMapLo(Reg),31);
MoveX86regToVariable(MipsRegMapLo(Reg),&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
@ -1045,7 +1129,7 @@ void CRegInfo::WriteBackRegisters ()
switch (MipsRegState(count)) {
case CRegInfo::STATE_UNKNOWN: break;
case CRegInfo::STATE_CONST_32:
if (!m_b32bitCore)
if (!b32BitCore())
{
if (!bEdiZero && (!MipsRegLo(count) || !(MipsRegLo(count) & 0x80000000))) {
XorX86RegToX86Reg(x86_EDI, x86_EDI);
@ -1063,7 +1147,7 @@ void CRegInfo::WriteBackRegisters ()
}
if (MipsRegLo(count) == 0) {
if (m_b32bitCore)
if (b32BitCore())
{
if (!bEdiZero)
{
@ -1073,7 +1157,7 @@ void CRegInfo::WriteBackRegisters ()
}
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
} else if (MipsRegLo(count) == 0xFFFFFFFF) {
if (m_b32bitCore)
if (b32BitCore())
{
if (!bEsiSign)
{

View File

@ -1,4 +1,5 @@
class CRegInfo :
private CGameSettings,
private CX86Ops,
private CSystemRegisters
{
@ -44,13 +45,17 @@ public:
RoundUp = 4,
};
public:
CRegInfo();
CRegInfo(const CRegInfo&);
~CRegInfo();
CRegInfo& operator=(const CRegInfo&);
bool operator==(const CRegInfo& right) const;
bool operator!=(const CRegInfo& right) const;
static REG_STATE ConstantsType ( __int64 Value );
void Initilize ( bool b32bitCore );
void FixRoundModel ( FPU_ROUND RoundMethod );
void ChangeFPURegFormat ( int Reg, FPU_STATE OldFormat, FPU_STATE NewFormat, FPU_ROUND RoundingModel );
void Load_FPR_ToTop ( int Reg, int RegToLoad, FPU_STATE Format);
@ -89,84 +94,81 @@ public:
inline bool Is32BitMapped(int Reg) const { return ((MipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)); }
inline bool Is64BitMapped(int Reg) const { return ((MipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_32BIT | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_X86_MAPPED)); }
inline _int64 cMipsReg_S ( int Reg ) const { return MIPS_RegVal[Reg].DW; }
inline DWORD cMipsRegLo ( int Reg ) const { return MIPS_RegVal[Reg].UW[0]; }
inline long cMipsRegLo_S ( int Reg ) const { return MIPS_RegVal[Reg].W[0]; }
inline DWORD cMipsRegHi ( int Reg ) const { return MIPS_RegVal[Reg].UW[1]; }
inline long cMipsRegHi_S ( int Reg ) const { return MIPS_RegVal[Reg].W[1]; }
inline _int64 cMipsReg_S ( int Reg ) const { return m_MIPS_RegVal[Reg].DW; }
inline DWORD cMipsRegLo ( int Reg ) const { return m_MIPS_RegVal[Reg].UW[0]; }
inline long cMipsRegLo_S ( int Reg ) const { return m_MIPS_RegVal[Reg].W[0]; }
inline DWORD cMipsRegHi ( int Reg ) const { return m_MIPS_RegVal[Reg].UW[1]; }
inline long cMipsRegHi_S ( int Reg ) const { return m_MIPS_RegVal[Reg].W[1]; }
inline REG_STATE MipsRegState ( int Reg ) const { return MIPS_RegState[Reg]; }
inline unsigned _int64 MipsReg ( int Reg ) const { return MIPS_RegVal[Reg].UDW; }
inline _int64 & MipsReg_S ( int Reg ) { return MIPS_RegVal[Reg].DW; }
inline DWORD & MipsRegLo ( int Reg ) { return MIPS_RegVal[Reg].UW[0]; }
inline long & MipsRegLo_S ( int Reg ) { return MIPS_RegVal[Reg].W[0]; }
inline DWORD & MipsRegHi ( int Reg ) { return MIPS_RegVal[Reg].UW[1]; }
inline long & MipsRegHi_S ( int Reg ) { return MIPS_RegVal[Reg].W[1]; }
inline CX86Ops::x86Reg MipsRegMapLo ( int Reg ) const { return RegMapLo[Reg]; }
inline CX86Ops::x86Reg MipsRegMapHi ( int Reg ) const { return RegMapHi[Reg]; }
inline bool X86Protected ( x86Reg Reg ) const { return x86reg_Protected[Reg]; }
inline REG_STATE MipsRegState ( int Reg ) const { return m_MIPS_RegState[Reg]; }
inline unsigned _int64 MipsReg ( int Reg ) const { return m_MIPS_RegVal[Reg].UDW; }
inline _int64 & MipsReg_S ( int Reg ) { return m_MIPS_RegVal[Reg].DW; }
inline DWORD & MipsRegLo ( int Reg ) { return m_MIPS_RegVal[Reg].UW[0]; }
inline long & MipsRegLo_S ( int Reg ) { return m_MIPS_RegVal[Reg].W[0]; }
inline DWORD & MipsRegHi ( int Reg ) { return m_MIPS_RegVal[Reg].UW[1]; }
inline long & MipsRegHi_S ( int Reg ) { return m_MIPS_RegVal[Reg].W[1]; }
inline CX86Ops::x86Reg MipsRegMapLo ( int Reg ) const { return m_RegMapLo[Reg]; }
inline CX86Ops::x86Reg MipsRegMapHi ( int Reg ) const { return m_RegMapHi[Reg]; }
inline bool X86Protected ( x86Reg Reg ) const { return m_x86reg_Protected[Reg]; }
inline DWORD GetX86MapOrder ( x86Reg Reg ) const { return x86reg_MapOrder[Reg]; }
inline bool GetX86Protected ( x86Reg Reg ) const { return x86reg_Protected[Reg]; }
inline REG_MAPPED GetX86Mapped ( x86Reg Reg ) const { return x86reg_MappedTo[Reg]; }
inline DWORD GetX86MapOrder ( x86Reg Reg ) const { return m_x86reg_MapOrder[Reg]; }
inline bool GetX86Protected ( x86Reg Reg ) const { return m_x86reg_Protected[Reg]; }
inline REG_MAPPED GetX86Mapped ( x86Reg Reg ) const { return m_x86reg_MappedTo[Reg]; }
inline DWORD GetBlockCycleCount ( void ) const { return m_CycleCount; }
inline void SetMipsReg ( int Reg, unsigned __int64 value ) { MIPS_RegVal[Reg].UDW = value; }
inline void SetMipsReg ( int Reg, unsigned __int64 value ) { m_MIPS_RegVal[Reg].UDW = value; }
inline void SetMipsRegMapLo ( int MipsReg, x86Reg Reg )
{
RegMapLo[MipsReg] = Reg;
m_RegMapLo[MipsReg] = Reg;
}
inline void SetMipsRegMapHi ( int MipsReg, x86Reg Reg )
{
RegMapHi[MipsReg] = Reg;
m_RegMapHi[MipsReg] = Reg;
}
inline void SetMipsRegState ( int MipsReg, REG_STATE State ) { MIPS_RegState[MipsReg] = State; }
inline void SetMipsRegState ( int MipsReg, REG_STATE State ) { m_MIPS_RegState[MipsReg] = State; }
inline void SetX86MapOrder ( x86Reg Reg, DWORD Order ) { x86reg_MapOrder[Reg] = Order; }
inline void SetX86Protected ( x86Reg Reg, bool Protected ) { x86reg_Protected[Reg] = Protected; }
inline void SetX86Mapped ( x86Reg Reg, REG_MAPPED Mapping ) { x86reg_MappedTo[Reg] = Mapping; }
inline void SetX86MapOrder ( x86Reg Reg, DWORD Order ) { m_x86reg_MapOrder[Reg] = Order; }
inline void SetX86Protected ( x86Reg Reg, bool Protected ) { m_x86reg_Protected[Reg] = Protected; }
inline void SetX86Mapped ( x86Reg Reg, REG_MAPPED Mapping ) { m_x86reg_MappedTo[Reg] = Mapping; }
inline void SetBlockCycleCount ( DWORD CyleCount ) { m_CycleCount = CyleCount; }
inline int & StackTopPos ( void ) { return Stack_TopPos; }
inline int & StackTopPos ( void ) { return m_Stack_TopPos; }
inline int & FpuMappedTo( int Reg) { return x86fpu_MappedTo[Reg]; }
inline FPU_STATE & FpuState(int Reg) { return x86fpu_State[Reg]; }
inline FPU_ROUND & FpuRoundingModel(int Reg) { return x86fpu_RoundingModel[Reg]; }
inline bool & FpuBeenUsed (void ) { return Fpu_Used; }
inline bool & FpuBeenUsed (void ) { return m_Fpu_Used; }
inline FPU_ROUND GetRoundingModel ( void ) const { return m_RoundingModel; }
inline void SetRoundingModel ( FPU_ROUND RoundingModel ) { m_RoundingModel = RoundingModel; }
private:
const char * RoundingModelName ( FPU_ROUND RoundType );
x86Reg UnMap_8BitTempReg ( void );
//r4k
REG_STATE MIPS_RegState[32];
MIPS_DWORD MIPS_RegVal[32];
x86Reg RegMapHi[32];
x86Reg RegMapLo[32];
REG_STATE m_MIPS_RegState[32];
MIPS_DWORD m_MIPS_RegVal[32];
x86Reg m_RegMapHi[32];
x86Reg m_RegMapLo[32];
REG_MAPPED x86reg_MappedTo[10];
DWORD x86reg_MapOrder[10];
bool x86reg_Protected[10];
REG_MAPPED m_x86reg_MappedTo[10];
DWORD m_x86reg_MapOrder[10];
bool m_x86reg_Protected[10];
DWORD m_CycleCount;
//FPU
int Stack_TopPos;
int m_Stack_TopPos;
int x86fpu_MappedTo[8];
FPU_STATE x86fpu_State[8];
BOOL x86fpu_StateChanged[8];
FPU_ROUND x86fpu_RoundingModel[8];
bool Fpu_Used;
bool m_Fpu_Used;
FPU_ROUND m_RoundingModel;
bool m_b32bitCore;
bool compare(const CRegInfo& right) const;
const char * RoundingModelName ( FPU_ROUND RoundType );
static unsigned int m_fpuControl;
};

View File

@ -160,52 +160,3 @@ void CRegInfo::Initilize ( void )
#endif
CRegInfo::REG_STATE CRegInfo::ConstantsType (__int64 Value)
{
if (((Value >> 32) == -1) && ((Value & 0x80000000) != 0)) { return STATE_CONST_32; }
if (((Value >> 32) == 0) && ((Value & 0x80000000) == 0)) { return STATE_CONST_32; }
return STATE_CONST_64;
}
bool CRegInfo::compare(const CRegInfo& right) const
{
int count;
for (count = 0; count < 32; count ++ ) {
if (MIPS_RegState[count] != right.MIPS_RegState[count])
{
return false;
}
if (MIPS_RegState[count] == STATE_UNKNOWN)
{
continue;
}
if (MIPS_RegVal[count].DW != right.MIPS_RegVal[count].DW)
{
return false;
}
}
for (count = 0; count < 10; count ++ ) {
if (x86reg_MappedTo[count] != right.x86reg_MappedTo[count]) { return false; }
if (x86reg_Protected[count] != right.x86reg_Protected[count]) { return false; }
if (x86reg_MapOrder[count] != right.x86reg_MapOrder[count]) { return false; }
}
if (m_CycleCount != right.m_CycleCount) { return false; }
if (Stack_TopPos != right.Stack_TopPos) { return false; }
for (count = 0; count < 8; count ++ ) {
if (x86fpu_MappedTo[count] != right.x86fpu_MappedTo[count]) { return false; }
if (x86fpu_State[count] != right.x86fpu_State[count]) { return false; }
if (x86fpu_RoundingModel[count] != right.x86fpu_RoundingModel[count]) { return false; }
}
if (Fpu_Used != right.Fpu_Used) { return false; }
if (GetRoundingModel() != right.GetRoundingModel()) { return false; }
return true;
}
bool CRegInfo::operator!=(const CRegInfo& right) const
{
return !compare(right);
}

View File

@ -37,6 +37,7 @@
/>
<Tool
Name="VCCLCompilerTool"
WarningLevel="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@ -618,6 +619,10 @@
RelativePath="N64 System\Recompiler\Jump Info.cpp"
>
</File>
<File
RelativePath=".\N64 System\Recompiler\Loop Analysis.cpp"
>
</File>
<File
RelativePath="N64 System\Recompiler\Recompiler Class.cpp"
>
@ -645,6 +650,14 @@
<File
RelativePath="N64 System\Recompiler\X86ops.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
WarningLevel="3"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
@ -674,6 +687,14 @@
<File
RelativePath="Plugins\Controller Plugin.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="Plugins\GFX plugin.cpp"
@ -1371,6 +1392,10 @@
RelativePath="N64 System\Recompiler\Jump Info.h"
>
</File>
<File
RelativePath=".\N64 System\Recompiler\Loop Analysis.h"
>
</File>
<File
RelativePath="N64 System\Recompiler\Recompiler Class.h"
>

View File

@ -1,25 +1,35 @@
#include "stdafx.h"
int CGameSettings::m_RefCount = 0;
bool CGameSettings::m_Registered = false;
bool CGameSettings::m_bUseTlb;
bool CGameSettings::m_bUseTlb;
DWORD CGameSettings::m_CountPerOp = 2;
DWORD CGameSettings::m_ViRefreshRate = 1500;
bool CGameSettings::m_DelayDP = false;
bool CGameSettings::m_DelaySI = false;
DWORD CGameSettings::m_RdramSize = 0;
bool CGameSettings::m_bFixedAudio;
bool CGameSettings::m_bSyncToAudio;
bool CGameSettings::m_bFastSP;
bool CGameSettings::m_b32Bit;
CGameSettings::CGameSettings()
{
m_RefCount += 1;
if (m_RefCount == 1)
if (_Settings && !m_Registered)
{
m_Registered = true;
_Settings->RegisterChangeCB(Game_UseTlb,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->RegisterChangeCB(Game_ViRefreshRate,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->RegisterChangeCB(Game_CounterFactor,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->RegisterChangeCB(Game_RDRamSize,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->RegisterChangeCB(Game_DelaySI,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->RegisterChangeCB(Game_DelayDP,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->RegisterChangeCB(Game_FixedAudio,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->RegisterChangeCB(Game_SyncViaAudio,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->RegisterChangeCB(Game_32Bit,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->RegisterChangeCB(Game_FastSP,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
RefreshSettings();
}
@ -28,7 +38,7 @@ CGameSettings::CGameSettings()
CGameSettings::~CGameSettings()
{
m_RefCount -= 1;
if (m_RefCount == 0)
if (m_Registered && m_RefCount == 0)
{
_Settings->UnregisterChangeCB(Game_UseTlb,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->UnregisterChangeCB(Game_ViRefreshRate,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
@ -36,15 +46,25 @@ CGameSettings::~CGameSettings()
_Settings->UnregisterChangeCB(Game_RDRamSize,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->UnregisterChangeCB(Game_DelaySI,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->UnregisterChangeCB(Game_DelayDP,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->UnregisterChangeCB(Game_FixedAudio,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->UnregisterChangeCB(Game_SyncViaAudio,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->UnregisterChangeCB(Game_32Bit,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->UnregisterChangeCB(Game_FastSP,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
m_Registered = false;
}
}
void CGameSettings::RefreshSettings()
{
m_bUseTlb = _Settings->LoadBool(Game_UseTlb);
m_bUseTlb = _Settings->LoadBool(Game_UseTlb);
m_ViRefreshRate = _Settings->LoadDword(Game_ViRefreshRate);
m_CountPerOp = _Settings->LoadDword(Game_CounterFactor);
m_RdramSize = _Settings->LoadDword(Game_RDRamSize);
m_DelaySI = _Settings->LoadBool(Game_DelaySI);
m_DelayDP = _Settings->LoadBool(Game_DelayDP);
m_CountPerOp = _Settings->LoadDword(Game_CounterFactor);
m_RdramSize = _Settings->LoadDword(Game_RDRamSize);
m_DelaySI = _Settings->LoadBool(Game_DelaySI);
m_DelayDP = _Settings->LoadBool(Game_DelayDP);
m_bFixedAudio = _Settings->LoadBool(Game_FixedAudio);
m_bSyncToAudio = m_bFixedAudio ? _Settings->LoadBool(Game_SyncViaAudio) : false;
m_b32Bit = _Settings->LoadBool(Game_32Bit);
m_bFastSP = _Settings->LoadBool(Game_FastSP);
}

View File

@ -6,12 +6,16 @@ public:
CGameSettings();
virtual ~CGameSettings();
static inline bool bUseTlb ( void ) { return m_bUseTlb; }
inline static DWORD CountPerOp ( void ) { return m_CountPerOp; }
static inline bool bUseTlb ( void ) { return m_bUseTlb; }
inline static DWORD CountPerOp ( void ) { return m_CountPerOp; }
inline static DWORD ViRefreshRate ( void ) { return m_ViRefreshRate; }
inline static bool bDelayDP ( void ) { return m_DelayDP; }
inline static bool bDelaySI ( void ) { return m_DelaySI; }
inline static DWORD RdramSize ( void ) { return m_RdramSize; }
inline static bool bFixedAudio ( void ) { return m_bFixedAudio; }
inline static bool bSyncToAudio ( void ) { return m_bSyncToAudio; }
inline static bool b32BitCore ( void ) { return m_b32Bit; }
inline static bool bFastSP ( void ) { return m_bFastSP; }
private:
static void StaticRefreshSettings (CGameSettings * _this)
@ -22,11 +26,17 @@ private:
void RefreshSettings ( void );
//Settings that can be changed on the fly
static bool m_bUseTlb;
static bool m_bUseTlb;
static DWORD m_CountPerOp;
static DWORD m_ViRefreshRate;
static bool m_DelayDP;
static bool m_DelaySI;
static DWORD m_RdramSize;
static int m_RefCount;
static bool m_bFixedAudio;
static bool m_bSyncToAudio;
static bool m_bFastSP;
static bool m_b32Bit;
static int m_RefCount;
static bool m_Registered;
};

View File

@ -7,11 +7,7 @@ bool CN64SystemSettings::m_bProfiling;
bool CN64SystemSettings::m_bBasicMode;
bool CN64SystemSettings::m_bLimitFPS;
bool CN64SystemSettings::m_bShowDListAListCount;
bool CN64SystemSettings::m_bFixedAudio;
bool CN64SystemSettings::m_bSyncToAudio;
bool CN64SystemSettings::m_bDisplayFrameRate;
bool CN64SystemSettings::m_bFastSP;
bool CN64SystemSettings::m_b32Bit;
CN64SystemSettings::CN64SystemSettings()
{
@ -27,10 +23,6 @@ CN64SystemSettings::CN64SystemSettings()
_Settings->RegisterChangeCB(GameRunning_LimitFPS,NULL,RefreshSettings);
_Settings->RegisterChangeCB(Game_FixedAudio,NULL,RefreshSettings);
_Settings->RegisterChangeCB(Game_SyncViaAudio,NULL,RefreshSettings);
_Settings->RegisterChangeCB(Game_32Bit,NULL,RefreshSettings);
_Settings->RegisterChangeCB(Game_FastSP,NULL,RefreshSettings);
RefreshSettings(NULL);
}
}
@ -48,11 +40,6 @@ CN64SystemSettings::~CN64SystemSettings()
_Settings->UnregisterChangeCB(Debugger_ShowDListAListCount,NULL,RefreshSettings);
_Settings->UnregisterChangeCB(GameRunning_LimitFPS,NULL,RefreshSettings);
_Settings->UnregisterChangeCB(Game_FixedAudio,NULL,RefreshSettings);
_Settings->UnregisterChangeCB(Game_SyncViaAudio,NULL,RefreshSettings);
_Settings->UnregisterChangeCB(Game_32Bit,NULL,RefreshSettings);
_Settings->UnregisterChangeCB(Game_FastSP,NULL,RefreshSettings);
}
}
@ -65,9 +52,4 @@ void CN64SystemSettings::RefreshSettings(void *)
m_bProfiling = _Settings->LoadBool(Debugger_ProfileCode);
m_bShowDListAListCount = _Settings->LoadBool(Debugger_ShowDListAListCount);
m_bLimitFPS = _Settings->LoadBool(GameRunning_LimitFPS);
m_bFixedAudio = _Settings->LoadBool(Game_FixedAudio);
m_bSyncToAudio = m_bFixedAudio ? _Settings->LoadBool(Game_SyncViaAudio) : false;
m_b32Bit = _Settings->LoadBool(Game_32Bit);
m_bFastSP = _Settings->LoadBool(Game_FastSP);
}

View File

@ -12,10 +12,6 @@ protected:
inline static bool bProfiling ( void ) { return m_bProfiling; }
inline static bool bShowDListAListCount ( void ) { return m_bShowDListAListCount; }
inline static bool bLimitFPS ( void ) { return m_bLimitFPS; }
inline static bool bFixedAudio ( void ) { return m_bFixedAudio; }
inline static bool bSyncToAudio ( void ) { return m_bSyncToAudio; }
inline static bool b32BitCore ( void ) { return m_b32Bit; }
inline static bool bFastSP ( void ) { return m_bFastSP; }
private:
static void RefreshSettings ( void * );
@ -25,11 +21,7 @@ private:
static bool m_bBasicMode;
static bool m_bLimitFPS;
static bool m_bShowDListAListCount;
static bool m_bFixedAudio;
static bool m_bSyncToAudio;
static bool m_bDisplayFrameRate;
static bool m_bFastSP;
static bool m_b32Bit;
static int m_RefCount;

View File

@ -506,7 +506,11 @@ bool CRomBrowser::FillRomInfo(ROM_INFO * pRomInfo) {
bool CRomBrowser::GetRomFileNames( strlist & FileList, const CPath & BaseDirectory, const stdstr & Directory, bool InWatchThread )
{
CPath SearchPath((const stdstr&)BaseDirectory,"*.*");
if (!BaseDirectory.DirectoryExists())
{
return false;
}
CPath SearchPath(BaseDirectory,"*.*");
SearchPath.AppendDirectory(Directory.c_str());
if (!SearchPath.FindFirst(CPath::_A_ALLFILES))