Porject64: Implement Recompiler LL and SC

This commit is contained in:
zilmar 2013-02-20 05:31:10 +11:00
parent c8394fb473
commit dd537b518c
6 changed files with 71 additions and 154 deletions

View File

@ -51,6 +51,7 @@ public:
virtual void Compile_LH ( void ) = 0;
virtual void Compile_LHU ( void ) = 0;
virtual void Compile_LW ( void ) = 0;
virtual void Compile_LL ( void ) = 0;
virtual void Compile_LWC1 ( void ) = 0;
virtual void Compile_LWU ( void ) = 0;
virtual void Compile_LWL ( void ) = 0;
@ -67,6 +68,7 @@ public:
virtual void Compile_SD ( void ) = 0;
virtual void Compile_SDL ( void ) = 0;
virtual void Compile_SDR ( void ) = 0;
virtual void Compile_SC ( void ) = 0;
virtual void Compile_SWC1 ( void ) = 0;
virtual void Compile_SDC1 ( void ) = 0;
};

View File

@ -2757,10 +2757,15 @@ void CMipsMemoryVM::Compile_LHU (void)
void CMipsMemoryVM::Compile_LW (void)
{
Compile_LW(true);
Compile_LW(true,false);
}
void CMipsMemoryVM::Compile_LW (bool ResultSigned)
void CMipsMemoryVM::Compile_LL (void)
{
Compile_LW(true,true);
}
void CMipsMemoryVM::Compile_LW (bool ResultSigned, bool bRecordLLBit)
{
OPCODE & Opcode = CRecompilerOps::m_Opcode;
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(Opcode.Hex,m_CompilePC));
@ -2775,11 +2780,19 @@ void CMipsMemoryVM::Compile_LW (bool ResultSigned)
TempReg1 = Map_MemoryStack(x86_Any,true);
sprintf(String,"%Xh",(short)Opcode.offset);
MoveVariableDispToX86Reg((void *)((DWORD)(short)Opcode.offset),String,GetMipsRegMapLo(Opcode.rt),TempReg1,1);
if (bRecordLLBit)
{
g_Notify->BreakPoint(__FILE__,__LINE__);
}
} else {
if (IsConst(Opcode.base)) {
DWORD Address = GetMipsRegLo(Opcode.base) + (short)Opcode.offset;
Map_GPR_32bit(Opcode.rt,ResultSigned,-1);
Compile_LW(GetMipsRegMapLo(Opcode.rt),Address);
if (bRecordLLBit)
{
g_Notify->BreakPoint(__FILE__,__LINE__);
}
} else {
if (g_System->bUseTlb()) {
if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); }
@ -2807,6 +2820,10 @@ void CMipsMemoryVM::Compile_LW (bool ResultSigned)
CompileReadTLBMiss(TempReg1,TempReg2);
Map_GPR_32bit(Opcode.rt,ResultSigned,-1);
MoveX86regPointerToX86reg(TempReg1, TempReg2,GetMipsRegMapLo(Opcode.rt));
if (bRecordLLBit)
{
MoveConstToVariable(1,_LLBit,"LLBit");
}
} else {
if (IsMapped(Opcode.base)) {
ProtectGPR(Opcode.base);
@ -2822,6 +2839,10 @@ void CMipsMemoryVM::Compile_LW (bool ResultSigned)
}
AndConstToX86Reg(GetMipsRegMapLo(Opcode.rt),0x1FFFFFFF);
MoveN64MemToX86reg(GetMipsRegMapLo(Opcode.rt),GetMipsRegMapLo(Opcode.rt));
if (bRecordLLBit)
{
MoveConstToVariable(1,_LLBit,"LLBit");
}
}
}
}
@ -3040,7 +3061,7 @@ void CMipsMemoryVM::Compile_LWR (void)
void CMipsMemoryVM::Compile_LWU (void)
{
Compile_LW(false);
Compile_LW(false,false);
}
void CMipsMemoryVM::Compile_LD (void)
@ -3349,12 +3370,26 @@ void CMipsMemoryVM::Compile_SH (void)
}
void CMipsMemoryVM::Compile_SW (void)
{
Compile_SW(false);
}
void CMipsMemoryVM::Compile_SC (void)
{
Compile_SW(true);
}
void CMipsMemoryVM::Compile_SW (bool bCheckLLbit)
{
OPCODE & Opcode = CRecompilerOps::m_Opcode;
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(Opcode.Hex,m_CompilePC));
x86Reg TempReg1, TempReg2;
if (Opcode.base == 29 && g_System->bFastSP()) {
if (bCheckLLbit)
{
g_Notify->BreakPoint(__FILE__,__LINE__);
}
if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); }
TempReg1 = Map_MemoryStack(x86_Any,true);
@ -3370,6 +3405,10 @@ void CMipsMemoryVM::Compile_SW (void)
if (IsConst(Opcode.base)) {
DWORD Address = GetMipsRegLo(Opcode.base) + (short)Opcode.offset;
if (bCheckLLbit)
{
g_Notify->BreakPoint(__FILE__,__LINE__);
}
if (IsConst(Opcode.rt)) {
Compile_SW_Const(GetMipsRegLo(Opcode.rt), Address);
} else if (IsMapped(Opcode.rt)) {
@ -3406,6 +3445,13 @@ void CMipsMemoryVM::Compile_SW (void)
ShiftRightUnsignImmed(TempReg2,12);
MoveVariableDispToX86Reg(m_TLB_WriteMap,"m_TLB_WriteMap",TempReg2,TempReg2,4);
CompileWriteTLBMiss(TempReg1,TempReg2);
BYTE * Jump = NULL;
if (bCheckLLbit)
{
CompConstToVariable(1,_LLBit,"_LLBit");
JneLabel8("LLBit_Continue",0);
Jump = m_RecompPos - 1;
}
if (IsConst(Opcode.rt)) {
MoveConstToX86regPointer(GetMipsRegLo(Opcode.rt),TempReg1, TempReg2);
} else if (IsMapped(Opcode.rt)) {
@ -3413,7 +3459,19 @@ void CMipsMemoryVM::Compile_SW (void)
} else {
MoveX86regToX86regPointer(Map_TempReg(x86_Any,Opcode.rt,FALSE),TempReg1, TempReg2);
}
if (bCheckLLbit)
{
CPU_Message(" ");
CPU_Message(" LLBit_Continue:");
SetJump8(Jump,m_RecompPos);
Map_GPR_32bit(Opcode.rt,false,-1);
MoveVariableToX86reg(_LLBit,"_LLBit",GetMipsRegMapLo(Opcode.rt));
}
} else {
if (bCheckLLbit)
{
g_Notify->BreakPoint(__FILE__,__LINE__);
}
AndConstToX86Reg(TempReg1,0x1FFFFFFF);
if (IsConst(Opcode.rt)) {
MoveConstToN64Mem(GetMipsRegLo(Opcode.rt),TempReg1);

View File

@ -61,6 +61,7 @@ public:
void Compile_LH ( void );
void Compile_LHU ( void );
void Compile_LW ( void );
void Compile_LL ( void );
void Compile_LWC1 ( void );
void Compile_LWU ( void );
void Compile_LWL ( void );
@ -77,6 +78,7 @@ public:
void Compile_SD ( void );
void Compile_SDL ( void );
void Compile_SDR ( void );
void Compile_SC ( void );
void Compile_SWC1 ( void );
void Compile_SDC1 ( void );
@ -109,7 +111,8 @@ private:
CMipsMemoryVM(const CMipsMemoryVM&); // Disable copy constructor
CMipsMemoryVM& operator=(const CMipsMemoryVM&); // Disable assignment
void Compile_LW ( bool ResultSigned );
void Compile_LW ( bool ResultSigned, bool bRecordLLbit );
void Compile_SW ( bool bCheckLLbit );
static void RdramChanged ( CMipsMemoryVM * _this );
static void ChangeSpStatus ( void );

View File

@ -1269,10 +1269,10 @@ bool CCodeSection::GenerateX86Code ( DWORD Test )
case R4300i_SDL: g_MMU->Compile_SDL(); break;
case R4300i_SDR: g_MMU->Compile_SDR(); break;
case R4300i_CACHE: CACHE(); break;
case R4300i_LL: LL(); break;
case R4300i_LL: g_MMU->Compile_LL(); break;
case R4300i_LWC1: g_MMU->Compile_LWC1(); break;
case R4300i_LDC1: g_MMU->Compile_LDC1(); break;
case R4300i_SC: SC(); break;
case R4300i_SC: g_MMU->Compile_SC(); break;
case R4300i_LD: g_MMU->Compile_LD(); break;
case R4300i_SWC1: g_MMU->Compile_SWC1(); break;
case R4300i_SDC1: g_MMU->Compile_SDC1(); break;

View File

@ -1755,152 +1755,6 @@ void CRecompilerOps::CACHE (void){
}
}
void CRecompilerOps::LL (void) {
g_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
x86Reg TempReg1, TempReg2;
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC));
if (m_Opcode.rt == 0) return;
if (IsConst(m_Opcode.base)) {
DWORD Address = GetMipsRegLo(m_Opcode.base) + (short)m_Opcode.offset;
Map_GPR_32bit(m_Opcode.rt,TRUE,-1);
g_MMU->Compile_LW(m_Section, GetMipsRegLo(m_Opcode.rt),Address);
MoveConstToVariable(1,_LLBit,"LLBit");
g_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
TranslateVaddr(Address, &Address);
#endif
MoveConstToVariable(Address,_LLAddr,"LLAddr");
return;
}
if (g_System->bUseTlb()) {
if (IsMapped(m_Opcode.rt)) { ProtectGPR(m_Opcode.rt); }
if (IsMapped(m_Opcode.base) && m_Opcode.offset == 0) {
ProtectGPR(m_Opcode.base);
TempReg1 = GetMipsRegLo(m_Opcode.base);
} else {
if (IsMapped(m_Opcode.base)) {
ProtectGPR(m_Opcode.base);
if (m_Opcode.offset != 0) {
TempReg1 = Map_TempReg(x86_Any,-1,FALSE);
LeaSourceAndOffset(TempReg1,GetMipsRegLo(m_Opcode.base),(short)m_Opcode.offset);
} else {
TempReg1 = Map_TempReg(x86_Any,m_Opcode.base,FALSE);
}
} else {
TempReg1 = Map_TempReg(x86_Any,m_Opcode.base,FALSE);
AddConstToX86Reg(TempReg1,(short)m_Opcode.immediate);
}
}
TempReg2 = Map_TempReg(x86_Any,-1,FALSE);
MoveX86RegToX86Reg(TempReg1, TempReg2);
ShiftRightUnsignImmed(TempReg2,12);
MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4);
CompileReadTLBMiss(m_Section,TempReg1,TempReg2);
Map_GPR_32bit(m_Opcode.rt,TRUE,-1);
MoveX86regPointerToX86reg(TempReg1, TempReg2,GetMipsRegLo(m_Opcode.rt));
MoveConstToVariable(1,_LLBit,"LLBit");
MoveX86regToVariable(TempReg1,_LLAddr,"LLAddr");
AddX86regToVariable(TempReg2,_LLAddr,"LLAddr");
SubConstFromVariable((DWORD)g_MMU->Rdram(),_LLAddr,"LLAddr");
} else {
if (IsMapped(m_Opcode.base)) {
ProtectGPR(m_Opcode.base);
if (m_Opcode.offset != 0) {
Map_GPR_32bit(m_Opcode.rt,TRUE,-1);
LeaSourceAndOffset(GetMipsRegLo(m_Opcode.rt),GetMipsRegLo(m_Opcode.base),(short)m_Opcode.offset);
} else {
Map_GPR_32bit(m_Opcode.rt,TRUE,m_Opcode.base);
}
} else {
Map_GPR_32bit(m_Opcode.rt,TRUE,m_Opcode.base);
AddConstToX86Reg(GetMipsRegMapLo(m_Opcode.rt),(short)m_Opcode.immediate);
}
AndConstToX86Reg(GetMipsRegLo(m_Opcode.rt),0x1FFFFFFF);
MoveX86regToVariable(GetMipsRegLo(m_Opcode.rt),_LLAddr,"LLAddr");
MoveN64MemToX86reg(GetMipsRegLo(m_Opcode.rt),GetMipsRegLo(m_Opcode.rt));
MoveConstToVariable(1,_LLBit,"LLBit");
}
#endif
}
void CRecompilerOps::SC (void){
#ifdef tofix
x86Reg TempReg1, TempReg2;
BYTE * Jump;
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC));
CompConstToVariable(1,_LLBit,"LLBit");
JneLabel32("LLBitNotSet",0);
Jump = (DWORD *)(m_RecompPos - 4);
if (IsConst(m_Opcode.base)) {
DWORD Address = GetMipsRegLo(m_Opcode.base) + (short)m_Opcode.offset;
if (IsConst(m_Opcode.rt)) {
g_MMU->Compile_SW_Const(GetMipsRegLo(m_Opcode.rt), Address);
} else if (IsMapped(m_Opcode.rt)) {
g_MMU->Compile_SW_Register(m_Section,GetMipsRegLo(m_Opcode.rt), Address);
} else {
g_MMU->Compile_SW_Register(m_Section,Map_TempReg(x86_Any,m_Opcode.rt,FALSE), Address);
}
CPU_Message(" LLBitNotSet:");
*((DWORD *)(Jump))=(BYTE)(m_RecompPos - Jump - 4);
Map_GPR_32bit(m_Opcode.rt,FALSE,-1);
MoveVariableToX86reg(_LLBit,"LLBit",GetMipsRegLo(m_Opcode.rt));
return;
}
if (IsMapped(m_Opcode.rt)) { ProtectGPR(m_Opcode.rt); }
if (IsMapped(m_Opcode.base)) {
ProtectGPR(m_Opcode.base);
if (m_Opcode.offset != 0) {
TempReg1 = Map_TempReg(x86_Any,-1,FALSE);
LeaSourceAndOffset(TempReg1,GetMipsRegLo(m_Opcode.base),(short)m_Opcode.offset);
} else {
TempReg1 = Map_TempReg(x86_Any,m_Opcode.base,FALSE);
}
UnProtectGPR(m_Opcode.base);
} else {
TempReg1 = Map_TempReg(x86_Any,m_Opcode.base,FALSE);
AddConstToX86Reg(TempReg1,(short)m_Opcode.immediate);
}
if (g_System->bUseTlb()) {
TempReg2 = Map_TempReg(x86_Any,-1,FALSE);
MoveX86RegToX86Reg(TempReg1, TempReg2);
ShiftRightUnsignImmed(TempReg2,12);
MoveVariableDispToX86Reg(TLB_WriteMap,"TLB_WriteMap",TempReg2,TempReg2,4);
//For tlb miss
//0041C522 85 C0 test eax,eax
//0041C524 75 01 jne 0041C527
if (IsConst(m_Opcode.rt)) {
MoveConstToX86regPointer(GetMipsRegLo(m_Opcode.rt),TempReg1, TempReg2);
} else if (IsMapped(m_Opcode.rt)) {
MoveX86regToX86regPointer(GetMipsRegLo(m_Opcode.rt),TempReg1, TempReg2);
} else {
MoveX86regToX86regPointer(Map_TempReg(x86_Any,m_Opcode.rt,FALSE),TempReg1, TempReg2);
}
} else {
AndConstToX86Reg(TempReg1,0x1FFFFFFF);
if (IsConst(m_Opcode.rt)) {
MoveConstToN64Mem(GetMipsRegLo(m_Opcode.rt),TempReg1);
} else if (IsMapped(m_Opcode.rt)) {
MoveX86regToN64Mem(GetMipsRegLo(m_Opcode.rt),TempReg1);
} else {
MoveX86regToN64Mem(Map_TempReg(x86_Any,m_Opcode.rt,FALSE),TempReg1);
}
}
CPU_Message(" LLBitNotSet:");
*((DWORD *)(Jump))=(BYTE)(m_RecompPos - Jump - 4);
Map_GPR_32bit(m_Opcode.rt,FALSE,-1);
MoveVariableToX86reg(_LLBit,"LLBit",GetMipsRegLo(m_Opcode.rt));
#endif
}
/********************** R4300i OpCodes: Special **********************/
void CRecompilerOps::SPECIAL_SLL (void) {
CPU_Message(" %X %s",m_CompilePC,R4300iOpcodeName(m_Opcode.Hex,m_CompilePC));

View File

@ -68,11 +68,11 @@ protected:
// static void SDL ( void );
// static void SDR ( void );
static void CACHE ( void );
static void LL ( void );
// static void LL ( void );
// static void LWC1 ( void );
// static void LDC1 ( void );
// static void LD ( void );
static void SC ( void );
// static void SC ( void );
// static void SWC1 ( void );
// static void SDC1 ( void );
// static void SD ( void );