Merge branch 'ABL-Refactor'
This commit is contained in:
commit
68d6692421
12990
Config/Project64.rdb
12990
Config/Project64.rdb
File diff suppressed because it is too large
Load Diff
|
@ -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,
|
||||
|
|
|
@ -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:");
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);\
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -461,7 +461,7 @@ protected:
|
|||
|
||||
class CRegisters:
|
||||
protected CSystemRegisters,
|
||||
protected CN64SystemSettings,
|
||||
protected CGameSettings,
|
||||
public CP0registers,
|
||||
public Rdram_InterfaceReg,
|
||||
public Mips_InterfaceReg,
|
||||
|
|
|
@ -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 ++) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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 );
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
};
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue