Merge branch 'ABL-Refactor'

This commit is contained in:
zilmar 2012-10-23 21:41:24 +11:00
commit 68d6692421
30 changed files with 2830 additions and 14558 deletions

File diff suppressed because it is too large Load Diff

View File

@ -276,7 +276,6 @@ enum LanguageStringID{
//Rom Options
ROM_CPU_STYLE = 520,
ROM_SMCM = 521,
ROM_MEM_SIZE = 522,
ROM_ABL = 523,
ROM_SAVE_TYPE = 524,

View File

@ -224,7 +224,6 @@ void CLanguage::LoadDefaultStrings (void) {
//Rom Options
DEF_STR(ROM_CPU_STYLE, "CPU core style:");
DEF_STR(ROM_SMCM, "Self-modifying code Method:");
DEF_STR(ROM_MEM_SIZE, "Memory Size:");
DEF_STR(ROM_ABL, "Advanced Block Linking:");
DEF_STR(ROM_SAVE_TYPE, "Default Save type:");

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

@ -8,7 +8,7 @@ void ExecuteInterpreterOps (DWORD /*Cycles*/)
_Notify->BreakPoint(__FILE__,__LINE__);
}
int DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) {
bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) {
OPCODE Command;
if (!_MMU->LW_VAddr(PC + 4, Command.Hex)) {

View File

@ -1,7 +1,7 @@
#include "stdafx.h"
//#include "../C Core/Logging.h"
int DelaySlotEffectsCompare ( DWORD PC, DWORD Reg1, DWORD Reg2 );
bool DelaySlotEffectsCompare ( DWORD PC, DWORD Reg1, DWORD Reg2 );
#define ADDRESS_ERROR_EXCEPTION(Address,FromRead) \
_Reg->DoAddressError(m_NextInstruction == JUMP,Address,FromRead);\

View File

@ -711,7 +711,7 @@ R4300iOp::Func * R4300iOp::BuildInterpreter (void )
return Jump_Opcode;
}
int DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2);
bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2);
void TestInterpreterJump (DWORD PC, DWORD TargetPC, int Reg1, int Reg2)
{
@ -2036,7 +2036,18 @@ void R4300iOp::COP1_S_DIV (void) {
void R4300iOp::COP1_S_SQRT (void) {
TEST_COP1_USABLE_EXCEPTION
_controlfp(*_RoundingModel,_MCW_RC);
*(float *)_FPR_S[m_Opcode.fd] = (float)sqrt(*(float *)_FPR_S[m_Opcode.fs]);
float * Dest = (float *)_FPR_S[m_Opcode.fd];
float * Source = (float *)_FPR_S[m_Opcode.fs];
_asm {
push esi
mov esi, dword ptr [Source]
fld dword ptr [esi]
fsqrt
mov esi, dword ptr [Dest]
fstp dword ptr [esi]
pop esi
}
}
void R4300iOp::COP1_S_ABS (void) {

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) {
@ -418,9 +425,9 @@ void CMipsMemoryVM::Compile_LW (x86Reg Reg, DWORD VAddr ) {
case 0x04400000:
switch (PAddr) {
case 0x04400010:
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp());
UpdateCounters(m_RegWorkingSet,false, true);
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp());
BeforeCallDirect(m_RegWorkingSet);
MoveConstToX86reg((DWORD)this,x86_ECX);
Call_Direct(AddressOf(&CMipsMemoryVM::UpdateHalfLine),"CMipsMemoryVM::UpdateHalfLine");
@ -437,9 +444,9 @@ void CMipsMemoryVM::Compile_LW (x86Reg Reg, DWORD VAddr ) {
case 0x04500004:
if (bFixedAudio())
{
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp());
UpdateCounters(m_RegWorkingSet,false, true);
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp());
BeforeCallDirect(m_RegWorkingSet);
MoveConstToX86reg((DWORD)_Audio,x86_ECX);
Call_Direct(AddressOf(&CAudio::GetLength),"CAudio::GetLength");
@ -954,9 +961,9 @@ void CMipsMemoryVM::Compile_SW_Const ( DWORD Value, DWORD VAddr ) {
switch (PAddr) {
case 0x04800000: MoveConstToVariable(Value,&_Reg->SI_DRAM_ADDR_REG,"SI_DRAM_ADDR_REG"); break;
case 0x04800004:
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp());
UpdateCounters(m_RegWorkingSet,false, true);
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp());
MoveConstToVariable(Value,&_Reg->SI_PIF_ADDR_RD64B_REG,"SI_PIF_ADDR_RD64B_REG");
BeforeCallDirect(m_RegWorkingSet);
MoveConstToX86reg((DWORD)((CPifRam *)this),x86_ECX);
@ -964,9 +971,9 @@ void CMipsMemoryVM::Compile_SW_Const ( DWORD Value, DWORD VAddr ) {
AfterCallDirect(m_RegWorkingSet);
break;
case 0x04800010:
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp());
UpdateCounters(m_RegWorkingSet,false, true);
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp());
MoveConstToVariable(Value,&_Reg->SI_PIF_ADDR_WR64B_REG,"SI_PIF_ADDR_WR64B_REG");
BeforeCallDirect(m_RegWorkingSet);
MoveConstToX86reg((DWORD)((CPifRam *)this),x86_ECX);
@ -1033,9 +1040,9 @@ void CMipsMemoryVM::Compile_SW_Register (x86Reg Reg, DWORD VAddr )
AfterCallDirect(m_RegWorkingSet);
break;
case 0x04040010:
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp());
UpdateCounters(m_RegWorkingSet,false, true);
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp());
MoveX86regToVariable(Reg,&RegModValue,"RegModValue");
BeforeCallDirect(m_RegWorkingSet);
Call_Direct(ChangeSpStatus,"ChangeSpStatus");
@ -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:
@ -1140,9 +1156,9 @@ void CMipsMemoryVM::Compile_SW_Register (x86Reg Reg, DWORD VAddr )
switch (PAddr) {
case 0x04500000: MoveX86regToVariable(Reg,&_Reg->AI_DRAM_ADDR_REG,"AI_DRAM_ADDR_REG"); break;
case 0x04500004:
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp());
UpdateCounters(m_RegWorkingSet,false, true);
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp()) ;
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp());
MoveX86regToVariable(Reg,&_Reg->AI_LEN_REG,"AI_LEN_REG");
BeforeCallDirect(m_RegWorkingSet);
if (bFixedAudio())
@ -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:
@ -3232,6 +3255,12 @@ void CMipsMemoryVM::Compile_SW (void)
if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); }
if (IsMapped(Opcode.base)) {
ProtectGPR(Opcode.base);
if (bDelaySI() || bDelayDP())
{
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - CountPerOp());
UpdateCounters(m_RegWorkingSet,false, true);
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + CountPerOp());
}
if (Opcode.offset != 0) {
TempReg1 = Map_TempReg(x86_Any,-1,FALSE);
LeaSourceAndOffset(TempReg1,MipsRegMapLo(Opcode.base),(short)Opcode.offset);

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

@ -879,7 +879,29 @@ void CN64System::UpdateSyncCPU (CN64System * const SecondCPU, DWORD const Cycles
//CC_Core::SetCurrentSystem(this);
}
void CN64System::SyncCPU (CN64System * const SecondCPU) {
void CN64System::SyncCPUPC (CN64System * const SecondCPU)
{
bool ErrorFound = false;
_SystemTimer->UpdateTimers();
if (m_Reg.m_PROGRAM_COUNTER != SecondCPU->m_Reg.m_PROGRAM_COUNTER) {
ErrorFound = true;
}
if (m_TLB != SecondCPU->m_TLB) { ErrorFound = true; }
if (m_SystemTimer != SecondCPU->m_SystemTimer) { ErrorFound = true; }
if (m_NextTimer != SecondCPU->m_NextTimer) { ErrorFound = true; }
if (ErrorFound) { DumpSyncErrors(SecondCPU); }
for (int i = (sizeof(m_LastSuccessSyncPC)/sizeof(m_LastSuccessSyncPC[0])) - 1; i > 0; i--) {
m_LastSuccessSyncPC[i] = m_LastSuccessSyncPC[i - 1];
}
m_LastSuccessSyncPC[0] = m_Reg.m_PROGRAM_COUNTER;
}
void CN64System::SyncCPU (CN64System * const SecondCPU)
{
bool ErrorFound = false;
//WriteTraceF(TraceError,"SyncCPU PC = %08X",m_Reg.m_PROGRAM_COUNTER);
@ -963,6 +985,11 @@ void CN64System::SyncSystem()
SyncCPU(_SyncSystem);
}
void CN64System::SyncSystemPC()
{
SyncCPUPC(_SyncSystem);
}
void CN64System::DumpSyncErrors (CN64System * SecondCPU) {
int count;
@ -1062,11 +1089,21 @@ void CN64System::DumpSyncErrors (CN64System * SecondCPU) {
}
Error.Log("\r\n");
for (count = 0; count < 32; count ++) {
Error.LogF("FPR[%s], 0x%08X%08X, 0x%08X%08X\r\n",CRegName::FPR[count],
m_Reg.m_FPR[count].W[1],m_Reg.m_FPR[count].W[0],
Error.LogF("FPR[%s],%*s0x%08X%08X, 0x%08X%08X\r\n",CRegName::FPR[count],
count < 10 ? 9 : 8," ",m_Reg.m_FPR[count].W[1],m_Reg.m_FPR[count].W[0],
SecondCPU->m_Reg.m_FPR[count].W[1],SecondCPU->m_Reg.m_FPR[count].W[0]);
}
Error.Log("\r\n");
for (count = 0; count < 32; count ++) {
Error.LogF("FPR_S[%s],%*s%f, %f\r\n",CRegName::FPR[count],
count < 10 ? 7 : 6," ",*(m_Reg.m_FPR_S[count]),*(SecondCPU->m_Reg.m_FPR_S[count]));
}
Error.Log("\r\n");
for (count = 0; count < 32; count ++) {
Error.LogF("FPR_D[%s],%*s%f, %f\r\n",CRegName::FPR[count],
count < 10 ? 7 : 6," ",*(m_Reg.m_FPR_D[count]),*(SecondCPU->m_Reg.m_FPR_D[count]));
}
Error.Log("\r\n");
Error.LogF("Rounding Model, 0x%08X, 0x%08X\r\n",m_Reg.m_RoundingModel,SecondCPU->m_Reg.m_RoundingModel);
Error.Log("\r\n");
for (count = 0; count < 32; count ++) {

View File

@ -68,7 +68,9 @@ public:
//For Sync CPU
void UpdateSyncCPU ( CN64System * const SecondCPU, DWORD const Cycles );
void SyncCPU ( CN64System * const SecondCPU );
void SyncCPUPC ( CN64System * const SecondCPU );
void SyncSystem ( void );
void SyncSystemPC ( void );
private:
//Make sure plugins can directly access this information
friend CGfxPlugin;

View File

@ -1,14 +1,38 @@
#include "stdafx.h"
bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2);
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_Test(1)
m_Test(1),
m_EnterSection(NULL)
{
CCodeSection * baseSection = new CCodeSection(this, VAddrEnter, 0, false);
if (baseSection == NULL)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
m_Sections.push_back(baseSection);
baseSection->AddParent(NULL);
baseSection->m_CompiledLocation = (BYTE *)-1;
baseSection->m_Cont.JumpPC = VAddrEnter;
baseSection->m_Cont.FallThrough = true;
baseSection->m_Cont.RegSet = baseSection->m_RegEnter;
m_EnterSection = new CCodeSection(this, VAddrEnter, 1, true);
if (m_EnterSection == NULL)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
baseSection->m_ContinueSection = m_EnterSection;
m_EnterSection->AddParent(baseSection);
m_Sections.push_back(m_EnterSection);
m_SectionMap.insert(SectionMap::value_type(VAddrEnter,m_EnterSection));
if (_TransVaddr->VAddrToRealAddr(VAddrEnter,*(reinterpret_cast<void **>(&m_MemLocation[0]))))
{
m_MemLocation[1] = m_MemLocation[0] + 1;
@ -21,13 +45,574 @@ CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos) :
AnalyseBlock();
}
CCodeBlock::~CCodeBlock()
{
for (SectionList::iterator itr = m_Sections.begin(); itr != m_Sections.end(); itr++)
{
CCodeSection * Section = *itr;
delete Section;
}
m_Sections.clear();
}
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))
{
return false;
}
if (TargetPC < m_EnterSection->m_EnterPC)
{
return false;
}
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(),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 && TargetPC != m_VAddrEnter)
{
CCodeSection * SplitSection = NULL;
for (SectionMap::const_iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++)
{
if (itr->first >= TargetPC)
{
break;
}
SplitSection = itr->second;
}
if (SplitSection == NULL)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (SplitSection->m_EndPC == (DWORD)-1)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
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);
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_EndPC = TargetPC - 4;
SplitSection->m_JumpSection = NULL;
SplitSection->m_ContinueSection = BaseSection;
SplitSection->SetContinueAddress(TargetPC - 4, TargetPC);
SplitSection->SetJumpAddress((DWORD)-1,(DWORD)-1,false);
}
}
}
return true;
}
bool CCodeBlock::CreateBlockLinkage ( CCodeSection * EnterSection )
{
CCodeSection * CurrentSection = EnterSection;
CPU_Message("Section %d",CurrentSection->m_SectionID);
for (DWORD TestPC = EnterSection->m_EnterPC, EndPC = ((EnterSection->m_EnterPC + 0x1000) & 0xFFFFF000); TestPC <= EndPC; TestPC += 4)
{
if (TestPC != EndPC)
{
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->m_EndPC = TestPC - 4;
CurrentSection = itr->second;
CPU_Message("Section %d",CurrentSection->m_SectionID);
if (EnterSection != m_EnterSection)
{
if (CurrentSection->m_JumpSection != NULL ||
CurrentSection->m_ContinueSection != NULL ||
CurrentSection->m_EndSection)
{
break;
}
}
}
} else {
CurrentSection->m_EndSection = true;
break;
}
bool LikelyBranch, EndBlock, IncludeDelaySlot, PermLoop;
DWORD TargetPC, ContinuePC;
CurrentSection->m_EndPC = TestPC;
if (!AnalyzeInstruction(TestPC, TargetPC, ContinuePC, LikelyBranch, IncludeDelaySlot, EndBlock, PermLoop))
{
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
if (TestPC + 4 == EndPC && IncludeDelaySlot)
{
TargetPC = (DWORD)-1;
ContinuePC = (DWORD)-1;
EndBlock = true;
}
if (TargetPC == (DWORD)-1 && !EndBlock)
{
if (ContinuePC != (DWORD)-1)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
continue;
}
if (EndBlock)
{
CPU_Message(__FUNCTION__ ": End Block");
CurrentSection->m_EndSection = true;
// find other sections that need compiling
break;
}
if (ContinuePC != (DWORD)-1)
{
CPU_Message(__FUNCTION__ ": SetContinueAddress TestPC = %X ContinuePC = %X",TestPC,ContinuePC);
CurrentSection->SetContinueAddress(TestPC, ContinuePC);
if (!SetSection(CurrentSection->m_ContinueSection, CurrentSection, ContinuePC,true,TestPC))
{
ContinuePC = (DWORD)-1;
}
}
if (LikelyBranch)
{
CPU_Message(__FUNCTION__ ": SetJumpAddress TestPC = %X Target = %X",TestPC,TestPC + 4);
CurrentSection->SetJumpAddress(TestPC, TestPC + 4,false);
if (SetSection(CurrentSection->m_JumpSection, CurrentSection, TestPC + 4,false,TestPC))
{
CCodeSection * JumpSection = CurrentSection->m_JumpSection;
JumpSection->m_EndPC = TestPC + 4;
JumpSection->SetJumpAddress(TestPC, TargetPC,false);
JumpSection->SetDelaySlot();
SetSection(JumpSection->m_JumpSection,CurrentSection->m_JumpSection,TargetPC,true,TestPC);
} else {
_Notify->BreakPoint(__FILE__,__LINE__);
}
}
else if (TargetPC != ((DWORD)-1))
{
CPU_Message(__FUNCTION__ ": SetJumpAddress TestPC = %X Target = %X",TestPC,TargetPC);
CurrentSection->SetJumpAddress(TestPC, TargetPC,PermLoop);
if (PermLoop || !SetSection(CurrentSection->m_JumpSection, CurrentSection, TargetPC,true,TestPC))
{
if (ContinuePC == (DWORD)-1)
{
CurrentSection->m_EndSection = true;
}
}
}
TestPC += IncludeDelaySlot ? 8 : 4;
//Find the next section
CCodeSection * NewSection = NULL;
for (SectionMap::const_iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++)
{
if (CurrentSection->m_JumpSection != NULL ||
CurrentSection->m_ContinueSection != NULL ||
CurrentSection->m_EndSection)
{
continue;
}
NewSection = itr->second;
break;
}
if (NewSection == NULL)
{
break;
}
if (CurrentSection == NewSection)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
CurrentSection = NewSection;
if (CurrentSection->m_JumpSection != NULL ||
CurrentSection->m_ContinueSection != NULL ||
CurrentSection->m_EndSection)
{
break;
}
TestPC = CurrentSection->m_EnterPC;
CPU_Message("a. Section %d",CurrentSection->m_SectionID);
TestPC -= 4;
}
for (SectionMap::iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++)
{
CCodeSection * Section = itr->second;
if (Section->m_JumpSection != NULL ||
Section->m_ContinueSection != NULL ||
Section->m_EndSection)
{
continue;
}
if (!CreateBlockLinkage(Section)) { return false; }
break;
}
if (CurrentSection->m_EndPC == (DWORD)-1)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
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, bool & PermLoop )
{
TargetPC = (DWORD)-1;
ContinuePC = (DWORD)-1;
LikelyBranch = false;
IncludeDelaySlot = false;
EndBlock = false;
PermLoop = false;
OPCODE Command;
if (!_MMU->LW_VAddr(PC, Command.Hex)) {
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
#ifdef _DEBUG
char * Name = R4300iOpcodeName(Command.Hex,PC);
CPU_Message(" 0x%08X %s",PC,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_JALR:
case R4300i_SPECIAL_JR:
EndBlock = true;
IncludeDelaySlot = true;
break;
case R4300i_SPECIAL_SYSCALL:
case R4300i_SPECIAL_BREAK:
EndBlock = true;
break;
default:
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
break;
case R4300i_REGIMM:
switch (Command.rt)
{
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__);
}
ContinuePC = PC + 8;
IncludeDelaySlot = true;
break;
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)
{
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;
case R4300i_REGIMM_BLTZL:
case R4300i_REGIMM_BGEZL:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
if (!DelaySlotEffectsCompare(PC,Command.rs,0))
{
PermLoop = true;
}
}
ContinuePC = PC + 8;
LikelyBranch = true;
IncludeDelaySlot = true;
break;
default:
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
break;
case R4300i_J:
TargetPC = (PC & 0xF0000000) + (Command.target << 2);
if (TargetPC == PC)
{
PermLoop = true;
}
IncludeDelaySlot = true;
break;
case R4300i_JAL:
EndBlock = true;
IncludeDelaySlot = true;
break;
case R4300i_BEQ:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC + 8)
{
TargetPC = (DWORD)-1;
} else {
if (Command.rs != 0 || Command.rt != 0)
{
ContinuePC = PC + 8;
} else if (TargetPC == PC) {
PermLoop = true;
}
IncludeDelaySlot = true;
}
break;
case R4300i_BNE:
case R4300i_BLEZ:
case R4300i_BGTZ:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC + 8)
{
TargetPC = (DWORD)-1;
} else {
if (TargetPC == PC)
{
if (!DelaySlotEffectsCompare(PC,Command.rs,Command.rt))
{
PermLoop = true;
}
}
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;
case R4300i_COP0_CO_ERET:
EndBlock = true;
break;
default:
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
} else {
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
break;
}
break;
case R4300i_CP1:
switch (Command.fmt) {
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)
{
TargetPC = (DWORD)-1;
} else {
if (TargetPC == PC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
ContinuePC = PC + 8;
IncludeDelaySlot = true;
}
break;
case R4300i_COP1_BC_BCFL:
case R4300i_COP1_BC_BCTL:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
ContinuePC = PC + 8;
LikelyBranch = true;
IncludeDelaySlot = true;
break;
default:
_Notify->BreakPoint(__FILE__,__LINE__);
}
break;
default:
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
break;
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_LDL: case R4300i_LDR:
case R4300i_LB: case R4300i_LH: case R4300i_LWL: case R4300i_LW:
case R4300i_LBU: case R4300i_LHU: case R4300i_LWR: case R4300i_LWU:
case R4300i_SB: case R4300i_SH: case R4300i_SWL: case R4300i_SW:
case R4300i_SWR: case R4300i_CACHE: case R4300i_LWC1: case R4300i_LDC1:
case R4300i_LD: case R4300i_SWC1: case R4300i_SDC1: case R4300i_SD:
break;
case R4300i_BEQL:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
if (!DelaySlotEffectsCompare(PC,Command.rs,Command.rt))
{
PermLoop = true;
}
}
if (Command.rs != 0 || Command.rt != 0)
{
ContinuePC = PC + 8;
}
IncludeDelaySlot = true;
LikelyBranch = true;
break;
case R4300i_BNEL:
case R4300i_BLEZL:
case R4300i_BGTZL:
TargetPC = PC + ((short)Command.offset << 2) + 4;
ContinuePC = PC + 8;
if (TargetPC == PC)
{
if (!DelaySlotEffectsCompare(PC,Command.rs,Command.rt))
{
PermLoop = true;
}
}
LikelyBranch = true;
IncludeDelaySlot = true;
break;
default:
if (Command.Hex == 0x7C1C97C0)
{
EndBlock = true;
break;
}
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
return true;
}
@ -42,20 +627,15 @@ bool CCodeBlock::Compile()
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 (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 +658,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

@ -3,24 +3,23 @@ class CCodeBlock :
{
public:
CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos );
~CCodeBlock();
bool Compile ( void );
inline DWORD VAddrEnter ( void ) const { return m_VAddrEnter; }
inline DWORD VAddrFirst ( void ) const { return m_VAddrFirst; }
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 int NoOfSections ( void ) const { return m_Sections.size(); }
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; }
inline void SetVAddrLast ( DWORD VAddr ) { m_VAddrLast = VAddr; }
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]; }
@ -29,16 +28,33 @@ public:
DWORD NextTest ( void );
private:
CCodeBlock(void); // Disable default constructor
CCodeBlock(const CCodeBlock&); // Disable copy constructor
CCodeBlock& operator=(const CCodeBlock&); // Disable assignment
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, bool & PermLoop );
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, bool PermLoop );
void SetContinueAddress ( DWORD JumpPC, DWORD TargetPC );
void CompileCop1Test ( void );
bool CreateSectionLinkage ( void );
bool GenerateX86Code ( DWORD Test );
@ -22,19 +25,24 @@ 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;
CCodeBlock * const m_BlockInfo;
const DWORD m_EnterPC;
const DWORD m_SectionID;
const DWORD m_EnterPC;
DWORD m_EndPC;
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 +52,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

@ -8,8 +8,8 @@ public:
stdstr BranchLabel;
DWORD * LinkLocation;
DWORD * LinkLocation2;
BOOL FallThrough;
BOOL PermLoop;
BOOL DoneDelaySlot;
bool FallThrough;
bool PermLoop;
bool DoneDelaySlot; //maybe deletable
CRegInfo RegSet;
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
#pragma once
class CCodeSection;
class CCodeBlock;
class LoopAnalysis
{
public:
LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section);
~LoopAnalysis();
bool SetupRegisterForLoop ( void );
private:
LoopAnalysis(void); // Disable default constructor
LoopAnalysis(const LoopAnalysis&); // Disable copy constructor
LoopAnalysis& operator=(const LoopAnalysis&); // Disable assignment
bool SetupEnterSection ( CCodeSection * Section, bool & bChanged, bool & bSkipedSection );
bool CheckLoopRegisterUsage ( CCodeSection * Section );
bool SyncRegState ( CRegInfo & RegSet, const CRegInfo& SyncReg );
void SetJumpRegSet ( CCodeSection * Section, const CRegInfo &Reg );
void SetContinueRegSet ( CCodeSection * Section, const CRegInfo &Reg );
/********************** 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 );
typedef std::map<int,CRegInfo *> RegisterMap;
RegisterMap m_EnterRegisters;
RegisterMap m_ContinueRegisters;
RegisterMap m_JumpRegisters;
CCodeSection * m_EnterSection;
CCodeBlock * m_BlockInfo;
DWORD m_PC;
CRegInfo m_Reg;
STEP_TYPE m_NextInstruction;
OPCODE m_Command;
DWORD m_Test;
};

View File

@ -21,17 +21,22 @@ void CRecompilerOps::CompileWriteTLBMiss (x86Reg AddressReg, x86Reg LookUpReg )
m_Section->CompileExit(m_CompilePC, m_CompilePC,m_RegWorkingSet,CExitInfo::TLBWriteMiss,FALSE,JeLabel32);
}
int DelaySlotEffectsCompare ( DWORD PC, DWORD Reg1, DWORD Reg2 );
bool DelaySlotEffectsCompare ( DWORD PC, DWORD Reg1, DWORD Reg2 );
/************************** Branch functions ************************/
void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc, BRANCH_TYPE BranchType, BOOL Link)
{
static int EffectDelaySlot, DoneJumpDelay, DoneContinueDelay;
static CRegInfo RegBeforeDelay;
static bool EffectDelaySlot;
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) {
@ -196,7 +201,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 +290,102 @@ 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 (!bLinkBlocks() || (m_CompilePC & 0xFFC) == 0xFFC)
{
m_Section->m_Jump.JumpPC = m_CompilePC;
m_Section->m_Jump.TargetPC = m_CompilePC + ((short)m_Opcode.offset << 2) + 4;
m_Section->m_Cont.JumpPC = m_CompilePC;
m_Section->m_Cont.TargetPC = m_CompilePC + 8;
} else {
if (m_Section->m_Jump.JumpPC != m_CompilePC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (m_Section->m_Cont.JumpPC != m_CompilePC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (m_Section->m_Cont.TargetPC != m_CompilePC + 8)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
}
if (m_Section->m_JumpSection != NULL) {
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_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_Jump.FallThrough = TRUE;
m_Section->m_Jump.LinkLocation = NULL;
m_Section->m_Jump.LinkLocation2 = NULL;
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_CompilePC & 0xFFC) == 0xFFC)
{
if (m_Section->m_Cont.FallThrough) { _Notify->BreakPoint(__FILE__,__LINE__); }
if (m_Section->m_Jump.LinkLocation != NULL) {
#ifndef EXTERNAL_RELEASE
_Notify->DisplayError("WTF .. problem with CRecompilerOps::BranchLikely");
#endif
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->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;
}
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;
} else {
m_NextInstruction = DO_DELAY_SLOT;
m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK;
}
}
} 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 {
@ -610,8 +642,11 @@ void CRecompilerOps::BEQ_Compare (void) {
m_Section->m_Jump.FallThrough = FALSE;
m_Section->m_Cont.FallThrough = TRUE;
}
} else if (IsMapped(m_Opcode.rs) && IsMapped(m_Opcode.rt)) {
if (Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) {
}
else if (IsMapped(m_Opcode.rs) && IsMapped(m_Opcode.rt))
{
if ((Is64Bit(m_Opcode.rs) || Is64Bit(m_Opcode.rt)) && !b32BitCore())
{
ProtectGPR(m_Opcode.rs);
ProtectGPR(m_Opcode.rt);
@ -1151,9 +1186,7 @@ void CRecompilerOps::BLTZ_Compare (void) {
void CRecompilerOps::BGEZ_Compare (void) {
if (IsConst(m_Opcode.rs)) {
if (Is64Bit(m_Opcode.rs)) {
#ifndef EXTERNAL_RELEASE
_Notify->DisplayError("BGEZ 1");
#endif
_Notify->BreakPoint(__FILE__,__LINE__);
CRecompilerOps::UnknownOpcode();
} else if (IsSigned(m_Opcode.rs)) {
if (MipsRegLo_S(m_Opcode.rs) >= 0) {
@ -1383,15 +1416,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;
@ -1984,24 +2012,13 @@ void CRecompilerOps::SPECIAL_JR (void) {
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);
m_Section->m_Jump.JumpPC = m_Section->m_Jump.TargetPC + 4;
m_Section->m_Jump.FallThrough = TRUE;
m_Section->m_Jump.LinkLocation = NULL;
m_Section->m_Jump.LinkLocation2 = NULL;
m_Section->m_Cont.FallThrough = FALSE;
m_Section->m_Cont.LinkLocation = NULL;
m_Section->m_Cont.LinkLocation2 = NULL;
} else {
m_Section->m_Jump.FallThrough = false;
m_Section->m_Jump.LinkLocation = NULL;
m_Section->m_Jump.LinkLocation2 = NULL;
m_Section->m_Cont.FallThrough = FALSE;
m_Section->m_Cont.LinkLocation = NULL;
m_Section->m_Cont.LinkLocation2 = NULL;
}
m_Section->m_Jump.FallThrough = false;
m_Section->m_Jump.LinkLocation = NULL;
m_Section->m_Jump.LinkLocation2 = NULL;
m_Section->m_Cont.FallThrough = FALSE;
m_Section->m_Cont.LinkLocation = NULL;
m_Section->m_Cont.LinkLocation2 = NULL;
if (DelaySlotEffectsCompare(m_CompilePC,m_Opcode.rs,0)) {
if (IsConst(m_Opcode.rs)) {
MoveConstToVariable(cMipsRegLo(m_Opcode.rs),_PROGRAM_COUNTER, "PROGRAM_COUNTER");
@ -2018,20 +2035,16 @@ void CRecompilerOps::SPECIAL_JR (void) {
} else {
UpdateCounters(m_RegWorkingSet,true,true);
if (IsConst(m_Opcode.rs)) {
m_Section->m_Jump.JumpPC = m_Section->m_Jump.TargetPC + 4;
m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->GenerateSectionLinkage();
MoveConstToVariable(cMipsRegLo(m_Opcode.rs),_PROGRAM_COUNTER, "PROGRAM_COUNTER");
} else if (IsMapped(m_Opcode.rs)) {
MoveX86regToVariable(MipsRegMapLo(m_Opcode.rs),_PROGRAM_COUNTER, "PROGRAM_COUNTER");
} else {
if (IsMapped(m_Opcode.rs)) {
MoveX86regToVariable(MipsRegMapLo(m_Opcode.rs),_PROGRAM_COUNTER, "PROGRAM_COUNTER");
} else {
MoveX86regToVariable(Map_TempReg(x86_Any,m_Opcode.rs,FALSE),_PROGRAM_COUNTER, "PROGRAM_COUNTER");
}
m_Section->CompileExit((DWORD)-1, (DWORD)-1,m_RegWorkingSet,CExitInfo::Normal,TRUE,NULL);
if (m_Section->m_JumpSection)
{
m_Section->GenerateSectionLinkage();
}
MoveX86regToVariable(Map_TempReg(x86_Any,m_Opcode.rs,FALSE),_PROGRAM_COUNTER, "PROGRAM_COUNTER");
}
m_Section->CompileExit((DWORD)-1, (DWORD)-1,m_RegWorkingSet,CExitInfo::Normal,TRUE,NULL);
if (m_Section->m_JumpSection)
{
m_Section->GenerateSectionLinkage();
}
}
m_NextInstruction = END_BLOCK;
@ -2069,7 +2082,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;
@ -2723,7 +2736,7 @@ void CRecompilerOps::SPECIAL_AND (void)
ProtectGPR(source1);
ProtectGPR(source2);
if (Is32Bit(source1) && Is32Bit(source2)) {
int Sign = (IsSigned(m_Opcode.rt) && IsSigned(m_Opcode.rs))?TRUE:FALSE;
bool Sign = (IsSigned(m_Opcode.rt) && IsSigned(m_Opcode.rs))?true:false;
Map_GPR_32bit(m_Opcode.rd,Sign,source1);
AndX86RegToX86Reg(MipsRegMapLo(m_Opcode.rd),MipsRegMapLo(source2));
} else if (Is32Bit(source1) || Is32Bit(source2)) {
@ -2773,13 +2786,13 @@ void CRecompilerOps::SPECIAL_AND (void)
}
} else {
DWORD Value = cMipsRegLo(ConstReg);
int Sign = FALSE;
if (IsSigned(ConstReg) && IsSigned(MappedReg)) { Sign = TRUE; }
bool Sign = false;
if (IsSigned(ConstReg) && IsSigned(MappedReg)) { Sign = true; }
if (Value != 0) {
Map_GPR_32bit(m_Opcode.rd,Sign,MappedReg);
AndConstToX86Reg(MipsRegMapLo(m_Opcode.rd),Value);
} else {
Map_GPR_32bit(m_Opcode.rd,FALSE, 0);
Map_GPR_32bit(m_Opcode.rd,false, 0);
}
}
}
@ -5132,7 +5145,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 +5155,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 );
@ -274,7 +274,7 @@ protected:
{
return m_RegWorkingSet.Free8BitX86Reg();
}
static inline void Map_GPR_32bit ( int Reg, BOOL SignValue, int MipsRegToLoad )
static inline void Map_GPR_32bit ( int Reg, bool SignValue, int MipsRegToLoad )
{
m_RegWorkingSet.Map_GPR_32bit(Reg,SignValue,MipsRegToLoad);
}

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 )
@ -454,30 +538,31 @@ CRegInfo::x86Reg CRegInfo::Map_MemoryStack ( x86Reg Reg, bool bMapRegister, bool
return Reg;
}
void CRegInfo::Map_GPR_32bit (int MipsReg, BOOL SignValue, int MipsRegToLoad)
void CRegInfo::Map_GPR_32bit (int MipsReg, bool SignValue, int MipsRegToLoad)
{
int count;
x86Reg Reg;
if (MipsReg == 0) {
#ifndef EXTERNAL_RELEASE
_Notify->DisplayError("Map_GPR_32bit\n\nWhy are you trying to map reg 0");
#endif
if (MipsReg == 0)
{
_Notify->BreakPoint(__FILE__,__LINE__);
return;
}
if (IsUnknown(MipsReg) || IsConst(MipsReg)) {
if (IsUnknown(MipsReg) || IsConst(MipsReg))
{
Reg = FreeX86Reg();
if (Reg < 0) {
#ifndef EXTERNAL_RELEASE
_Notify->DisplayError("Map_GPR_32bit\n\nOut of registers");
_Notify->BreakPoint(__FILE__,__LINE__);
#endif
_Notify->BreakPoint(__FILE__,__LINE__);
return;
}
CPU_Message(" regcache: allocate %s to %s",x86_Name(Reg),CRegName::GPR[MipsReg]);
} else {
if (Is64Bit(MipsReg)) {
if (Is64Bit(MipsReg))
{
CPU_Message(" regcache: unallocate %s from high 32bit of %s",x86_Name(MipsRegMapHi(MipsReg)),CRegName::GPR_Hi[MipsReg]);
SetX86MapOrder(MipsRegMapHi(MipsReg),0);
SetX86Mapped(MipsRegMapHi(MipsReg),NotMapped);
@ -489,17 +574,21 @@ void CRegInfo::Map_GPR_32bit (int MipsReg, BOOL SignValue, int MipsRegToLoad)
for (count = 0; count < 10; count ++)
{
DWORD Count = GetX86MapOrder((x86Reg)count);
if ( Count > 0) {
if ( Count > 0)
{
SetX86MapOrder((x86Reg)count,Count + 1);
}
}
SetX86MapOrder(Reg,1);
if (MipsRegToLoad > 0) {
if (IsUnknown(MipsRegToLoad)) {
if (MipsRegToLoad > 0)
{
if (IsUnknown(MipsRegToLoad))
{
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0],CRegName::GPR_Lo[MipsRegToLoad],Reg);
} else if (IsMapped(MipsRegToLoad)) {
if (MipsReg != MipsRegToLoad) {
if (MipsReg != MipsRegToLoad)
{
MoveX86RegToX86Reg(MipsRegMapLo(MipsRegToLoad),Reg);
}
} else {
@ -543,7 +632,11 @@ void CRegInfo::Map_GPR_64bit ( int MipsReg, int MipsRegToLoad)
if (Is32Bit(MipsReg)) {
SetX86Protected(x86lo,TRUE);
x86Hi = FreeX86Reg();
if (x86Hi < 0) { _Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); return; }
if (x86Hi == x86_Unknown)
{
_Notify->BreakPoint(__FILE__,__LINE__);
return;
}
SetX86Protected(x86Hi,TRUE);
CPU_Message(" regcache: allocate %s to hi word of %s",x86_Name(x86Hi),CRegName::GPR[MipsReg]);
@ -939,7 +1032,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 +1138,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 +1156,7 @@ void CRegInfo::WriteBackRegisters ()
}
if (MipsRegLo(count) == 0) {
if (m_b32bitCore)
if (b32BitCore())
{
if (!bEdiZero)
{
@ -1073,7 +1166,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)
{
@ -1114,11 +1207,9 @@ void CRegInfo::WriteBackRegisters ()
}
SetMipsRegState(count, CRegInfo::STATE_UNKNOWN);
break;
#ifndef EXTERNAL_RELEASE
default:
_Notify->DisplayError("Unknown State: %d\nin WriteBackRegisters",MipsRegState(count));
CPU_Message(__FUNCTION__ ": Unknown State: %d reg %d (%s)",MipsRegState(count),count,CRegName::GPR[count])
_Notify->BreakPoint(__FILE__,__LINE__);
#endif
}
}
}

View File

@ -1,15 +1,17 @@
class CRegInfo :
private CGameSettings,
private CX86Ops,
private CSystemRegisters
{
public:
//enums
enum REG_STATE {
STATE_UNKNOWN = 0,
STATE_KNOWN_VALUE = 1,
STATE_X86_MAPPED = 2,
STATE_SIGN = 4,
STATE_32BIT = 8,
STATE_UNKNOWN = 0x00,
STATE_KNOWN_VALUE = 0x01,
STATE_X86_MAPPED = 0x02,
STATE_SIGN = 0x04,
STATE_32BIT = 0x08,
STATE_MODIFIED = 0x10,
STATE_MAPPED_64 = (STATE_KNOWN_VALUE | STATE_X86_MAPPED), // = 3
STATE_MAPPED_32_ZERO = (STATE_KNOWN_VALUE | STATE_X86_MAPPED | STATE_32BIT), // = 11
@ -44,13 +46,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);
@ -61,7 +67,7 @@ public:
x86Reg FreeX86Reg ( void );
x86Reg Free8BitX86Reg ( void );
void Map_GPR_32bit ( int MipsReg, BOOL SignValue, int MipsRegToLoad );
void Map_GPR_32bit ( int MipsReg, bool SignValue, int MipsRegToLoad );
void Map_GPR_64bit ( int MipsReg, int MipsRegToLoad );
x86Reg Get_MemoryStack ( void ) const;
x86Reg Map_MemoryStack ( x86Reg Reg, bool bMapRegister, bool LoadValue = true );
@ -76,6 +82,7 @@ public:
inline bool IsKnown(int Reg) const { return ((MipsRegState(Reg) & STATE_KNOWN_VALUE) != 0); }
inline bool IsUnknown(int Reg) const { return ((MipsRegState(Reg) & STATE_KNOWN_VALUE) == 0); }
inline bool IsModified(int Reg) const { return ((MipsRegState(Reg) & STATE_MODIFIED) != 0); }
inline bool IsMapped(int Reg) const { return ((MipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_X86_MAPPED)) == (STATE_KNOWN_VALUE | STATE_X86_MAPPED)); }
inline bool IsConst(int Reg) const { return ((MipsRegState(Reg) & (STATE_KNOWN_VALUE | STATE_X86_MAPPED)) == STATE_KNOWN_VALUE); }
@ -89,84 +96,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"
@ -50,6 +51,7 @@
<Tool
Name="VCLinkerTool"
SubSystem="2"
DataExecutionPrevention="1"
/>
<Tool
Name="VCALinkTool"
@ -107,6 +109,7 @@
/>
<Tool
Name="VCLinkerTool"
DataExecutionPrevention="1"
/>
<Tool
Name="VCALinkTool"
@ -165,6 +168,7 @@
/>
<Tool
Name="VCLinkerTool"
DataExecutionPrevention="1"
/>
<Tool
Name="VCALinkTool"
@ -606,6 +610,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"
>
@ -633,6 +641,14 @@
<File
RelativePath="N64 System\Recompiler\X86ops.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
WarningLevel="3"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
@ -662,6 +678,14 @@
<File
RelativePath="Plugins\Controller Plugin.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
WarningLevel="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="Plugins\GFX plugin.cpp"
@ -1351,6 +1375,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 (_Settings && 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

@ -105,7 +105,7 @@ void CSettings::AddHowToHandleSetting ()
AddHandler(Rdb_GoodName, new CSettingTypeRomDatabase("Good Name",Game_GameName));
AddHandler(Rdb_SaveChip, new CSettingTypeRDBSaveChip("Save Type",SaveChip_Auto));
AddHandler(Rdb_CpuType, new CSettingTypeRDBCpuType("CPU Type",CPU_Recompiler));
AddHandler(Rdb_CpuType, new CSettingTypeRDBCpuType("CPU Type",CPU_SyncCores));
AddHandler(Rdb_RDRamSize, new CSettingTypeRDBRDRamSize("RDRAM Size",0x400000));
AddHandler(Rdb_CounterFactor, new CSettingTypeRomDatabase("Counter Factor",2));
AddHandler(Rdb_UseTlb, new CSettingTypeRDBYesNo("Use TLB",true));
@ -128,7 +128,7 @@ void CSettings::AddHowToHandleSetting ()
AddHandler(Rdb_ScreenHertz, new CSettingTypeRomDatabase("ScreenHertz",60));
AddHandler(Rdb_FuncLookupMode, new CSettingTypeRomDatabase("FuncFind",FuncFind_PhysicalLookup));
AddHandler(Rdb_RegCache, new CSettingTypeRDBYesNo("Reg Cache",true));
AddHandler(Rdb_BlockLinking, new CSettingTypeRDBOnOff("Linking",false));
AddHandler(Rdb_BlockLinking, new CSettingTypeRDBOnOff("Linking",true));
AddHandler(Rdb_SMM_Cache, new CSettingTypeRomDatabase("SMM-Cache",true));
AddHandler(Rdb_SMM_StoreInstruc, new CSettingTypeRomDatabase("SMM-StoreInstr",false));
AddHandler(Rdb_SMM_PIDMA, new CSettingTypeRomDatabase("SMM-PI DMA",true));

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