[Project64] Get Interpreter Ops to use standard types

This commit is contained in:
zilmar 2015-11-09 07:55:32 +11:00
parent 1ace31216d
commit e85c1665b1
8 changed files with 3791 additions and 3809 deletions

View File

@ -12,446 +12,444 @@
R4300iOp::Func * CInterpreterCPU::m_R4300i_Opcode = NULL; R4300iOp::Func * CInterpreterCPU::m_R4300i_Opcode = NULL;
void ExecuteInterpreterOps (DWORD /*Cycles*/) void ExecuteInterpreterOps(uint32_t /*Cycles*/)
{ {
g_Notify->BreakPoint(__FILEW__,__LINE__); g_Notify->BreakPoint(__FILEW__, __LINE__);
} }
bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2)
{ {
OPCODE Command; OPCODE Command;
if (!g_MMU->LW_VAddr(PC + 4, Command.Hex)) if (!g_MMU->LW_VAddr(PC + 4, Command.Hex))
{ {
//g_Notify->DisplayError(L"Failed to load word 2"); //g_Notify->DisplayError(L"Failed to load word 2");
//ExitThread(0); //ExitThread(0);
return true; return true;
} }
switch (Command.op) switch (Command.op)
{ {
case R4300i_SPECIAL: case R4300i_SPECIAL:
switch (Command.funct) switch (Command.funct)
{ {
case R4300i_SPECIAL_SLL: case R4300i_SPECIAL_SLL:
case R4300i_SPECIAL_SRL: case R4300i_SPECIAL_SRL:
case R4300i_SPECIAL_SRA: case R4300i_SPECIAL_SRA:
case R4300i_SPECIAL_SLLV: case R4300i_SPECIAL_SLLV:
case R4300i_SPECIAL_SRLV: case R4300i_SPECIAL_SRLV:
case R4300i_SPECIAL_SRAV: case R4300i_SPECIAL_SRAV:
case R4300i_SPECIAL_MFHI: case R4300i_SPECIAL_MFHI:
case R4300i_SPECIAL_MTHI: case R4300i_SPECIAL_MTHI:
case R4300i_SPECIAL_MFLO: case R4300i_SPECIAL_MFLO:
case R4300i_SPECIAL_MTLO: case R4300i_SPECIAL_MTLO:
case R4300i_SPECIAL_DSLLV: case R4300i_SPECIAL_DSLLV:
case R4300i_SPECIAL_DSRLV: case R4300i_SPECIAL_DSRLV:
case R4300i_SPECIAL_DSRAV: case R4300i_SPECIAL_DSRAV:
case R4300i_SPECIAL_ADD: case R4300i_SPECIAL_ADD:
case R4300i_SPECIAL_ADDU: case R4300i_SPECIAL_ADDU:
case R4300i_SPECIAL_SUB: case R4300i_SPECIAL_SUB:
case R4300i_SPECIAL_SUBU: case R4300i_SPECIAL_SUBU:
case R4300i_SPECIAL_AND: case R4300i_SPECIAL_AND:
case R4300i_SPECIAL_OR: case R4300i_SPECIAL_OR:
case R4300i_SPECIAL_XOR: case R4300i_SPECIAL_XOR:
case R4300i_SPECIAL_NOR: case R4300i_SPECIAL_NOR:
case R4300i_SPECIAL_SLT: case R4300i_SPECIAL_SLT:
case R4300i_SPECIAL_SLTU: case R4300i_SPECIAL_SLTU:
case R4300i_SPECIAL_DADD: case R4300i_SPECIAL_DADD:
case R4300i_SPECIAL_DADDU: case R4300i_SPECIAL_DADDU:
case R4300i_SPECIAL_DSUB: case R4300i_SPECIAL_DSUB:
case R4300i_SPECIAL_DSUBU: case R4300i_SPECIAL_DSUBU:
case R4300i_SPECIAL_DSLL: case R4300i_SPECIAL_DSLL:
case R4300i_SPECIAL_DSRL: case R4300i_SPECIAL_DSRL:
case R4300i_SPECIAL_DSRA: case R4300i_SPECIAL_DSRA:
case R4300i_SPECIAL_DSLL32: case R4300i_SPECIAL_DSLL32:
case R4300i_SPECIAL_DSRL32: case R4300i_SPECIAL_DSRL32:
case R4300i_SPECIAL_DSRA32: case R4300i_SPECIAL_DSRA32:
if (Command.rd == 0) if (Command.rd == 0)
{ {
return false; return false;
} }
if (Command.rd == Reg1 || Command.rd == Reg2) if (Command.rd == Reg1 || Command.rd == Reg2)
{ {
return true; return true;
} }
break; break;
case R4300i_SPECIAL_MULT: case R4300i_SPECIAL_MULT:
case R4300i_SPECIAL_MULTU: case R4300i_SPECIAL_MULTU:
case R4300i_SPECIAL_DIV: case R4300i_SPECIAL_DIV:
case R4300i_SPECIAL_DIVU: case R4300i_SPECIAL_DIVU:
case R4300i_SPECIAL_DMULT: case R4300i_SPECIAL_DMULT:
case R4300i_SPECIAL_DMULTU: case R4300i_SPECIAL_DMULTU:
case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIV:
case R4300i_SPECIAL_DDIVU: case R4300i_SPECIAL_DDIVU:
break; break;
default: default:
if (g_Settings->LoadBool(Debugger_Enabled)) if (g_Settings->LoadBool(Debugger_Enabled))
{ {
g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?",R4300iOpcodeName(Command.Hex,PC+4), PC).ToUTF16().c_str()); g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?", R4300iOpcodeName(Command.Hex, PC + 4), PC).ToUTF16().c_str());
} }
return true; return true;
} }
break; break;
case R4300i_CP0: case R4300i_CP0:
switch (Command.rs) switch (Command.rs)
{ {
case R4300i_COP0_MT: break; case R4300i_COP0_MT: break;
case R4300i_COP0_MF: case R4300i_COP0_MF:
if (Command.rt == 0) if (Command.rt == 0)
{ {
return false; return false;
} }
if (Command.rt == Reg1 || Command.rt == Reg2) if (Command.rt == Reg1 || Command.rt == Reg2)
{ {
return true; return true;
} }
break; break;
default: default:
if ( (Command.rs & 0x10 ) != 0 ) if ((Command.rs & 0x10) != 0)
{ {
switch (Command.funct) switch (Command.funct)
{ {
case R4300i_COP0_CO_TLBR: break; case R4300i_COP0_CO_TLBR: break;
case R4300i_COP0_CO_TLBWI: break; case R4300i_COP0_CO_TLBWI: break;
case R4300i_COP0_CO_TLBWR: break; case R4300i_COP0_CO_TLBWR: break;
case R4300i_COP0_CO_TLBP: break; case R4300i_COP0_CO_TLBP: break;
default: default:
if (g_Settings->LoadBool(Debugger_Enabled)) if (g_Settings->LoadBool(Debugger_Enabled))
{ {
g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?\n6",R4300iOpcodeName(Command.Hex,PC+4), PC).ToUTF16().c_str()); g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?\n6", R4300iOpcodeName(Command.Hex, PC + 4), PC).ToUTF16().c_str());
} }
return true; return true;
} }
} }
else else
{ {
if (g_Settings->LoadBool(Debugger_Enabled)) if (g_Settings->LoadBool(Debugger_Enabled))
{ {
g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?\n7",R4300iOpcodeName(Command.Hex,PC+4), PC).ToUTF16().c_str()); g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?\n7", R4300iOpcodeName(Command.Hex, PC + 4), PC).ToUTF16().c_str());
} }
return true; return true;
} }
} }
break; break;
case R4300i_CP1: case R4300i_CP1:
switch (Command.fmt) switch (Command.fmt)
{ {
case R4300i_COP1_MF: case R4300i_COP1_MF:
if (Command.rt == 0) if (Command.rt == 0)
{ {
return false; return false;
} }
if (Command.rt == Reg1 || Command.rt == Reg2) if (Command.rt == Reg1 || Command.rt == Reg2)
{ {
return true; return true;
} }
break; break;
case R4300i_COP1_CF: break; case R4300i_COP1_CF: break;
case R4300i_COP1_MT: break; case R4300i_COP1_MT: break;
case R4300i_COP1_CT: break; case R4300i_COP1_CT: break;
case R4300i_COP1_S: break; case R4300i_COP1_S: break;
case R4300i_COP1_D: break; case R4300i_COP1_D: break;
case R4300i_COP1_W: break; case R4300i_COP1_W: break;
case R4300i_COP1_L: break; case R4300i_COP1_L: break;
default: default:
if (g_Settings->LoadBool(Debugger_Enabled)) if (g_Settings->LoadBool(Debugger_Enabled))
{ {
g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?",R4300iOpcodeName(Command.Hex,PC+4), PC).ToUTF16().c_str()); g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?", R4300iOpcodeName(Command.Hex, PC + 4), PC).ToUTF16().c_str());
} }
return true; return true;
} }
break; break;
case R4300i_ANDI: case R4300i_ANDI:
case R4300i_ORI: case R4300i_ORI:
case R4300i_XORI: case R4300i_XORI:
case R4300i_LUI: case R4300i_LUI:
case R4300i_ADDI: case R4300i_ADDI:
case R4300i_ADDIU: case R4300i_ADDIU:
case R4300i_SLTI: case R4300i_SLTI:
case R4300i_SLTIU: case R4300i_SLTIU:
case R4300i_DADDI: case R4300i_DADDI:
case R4300i_DADDIU: case R4300i_DADDIU:
case R4300i_LB: case R4300i_LB:
case R4300i_LH: case R4300i_LH:
case R4300i_LW: case R4300i_LW:
case R4300i_LWL: case R4300i_LWL:
case R4300i_LWR: case R4300i_LWR:
case R4300i_LDL: case R4300i_LDL:
case R4300i_LDR: case R4300i_LDR:
case R4300i_LBU: case R4300i_LBU:
case R4300i_LHU: case R4300i_LHU:
case R4300i_LD: case R4300i_LD:
case R4300i_LWC1: case R4300i_LWC1:
case R4300i_LDC1: case R4300i_LDC1:
if (Command.rt == 0) if (Command.rt == 0)
{ {
return false; return false;
} }
if (Command.rt == Reg1 || Command.rt == Reg2) if (Command.rt == Reg1 || Command.rt == Reg2)
{ {
return true; return true;
} }
break; break;
case R4300i_CACHE: break; case R4300i_CACHE: break;
case R4300i_SB: break; case R4300i_SB: break;
case R4300i_SH: break; case R4300i_SH: break;
case R4300i_SW: break; case R4300i_SW: break;
case R4300i_SWR: break; case R4300i_SWR: break;
case R4300i_SWL: break; case R4300i_SWL: break;
case R4300i_SWC1: break; case R4300i_SWC1: break;
case R4300i_SDC1: break; case R4300i_SDC1: break;
case R4300i_SD: break; case R4300i_SD: break;
default: default:
if (g_Settings->LoadBool(Debugger_Enabled)) if (g_Settings->LoadBool(Debugger_Enabled))
{ {
g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?",R4300iOpcodeName(Command.Hex,PC+4), PC).ToUTF16().c_str()); g_Notify->DisplayError(stdstr_f("Does %s effect Delay slot at %X?", R4300iOpcodeName(Command.Hex, PC + 4), PC).ToUTF16().c_str());
} }
return true; return true;
} }
return false; return false;
} }
void CInterpreterCPU::BuildCPU() void CInterpreterCPU::BuildCPU()
{ {
R4300iOp::m_TestTimer = false; R4300iOp::m_TestTimer = false;
R4300iOp::m_NextInstruction = NORMAL; R4300iOp::m_NextInstruction = NORMAL;
R4300iOp::m_JumpToLocation = 0; R4300iOp::m_JumpToLocation = 0;
if (g_Settings->LoadBool(Game_32Bit)) if (g_Settings->LoadBool(Game_32Bit))
{ {
m_R4300i_Opcode = R4300iOp32::BuildInterpreter(); m_R4300i_Opcode = R4300iOp32::BuildInterpreter();
} }
else else
{ {
m_R4300i_Opcode = R4300iOp::BuildInterpreter(); m_R4300i_Opcode = R4300iOp::BuildInterpreter();
} }
} }
void CInterpreterCPU::InPermLoop() void CInterpreterCPU::InPermLoop()
{ {
// *** Changed ***/ // *** Changed ***/
//if (CPU_Type == CPU_SyncCores) //if (CPU_Type == CPU_SyncCores)
//{ //{
// SyncRegisters.CP0[9] +=5; // SyncRegisters.CP0[9] +=5;
//} //}
/* Interrupts enabled */ /* Interrupts enabled */
if (( g_Reg->STATUS_REGISTER & STATUS_IE ) == 0 || if ((g_Reg->STATUS_REGISTER & STATUS_IE) == 0 ||
( g_Reg->STATUS_REGISTER & STATUS_EXL ) != 0 || (g_Reg->STATUS_REGISTER & STATUS_EXL) != 0 ||
( g_Reg->STATUS_REGISTER & STATUS_ERL ) != 0 || (g_Reg->STATUS_REGISTER & STATUS_ERL) != 0 ||
( g_Reg->STATUS_REGISTER & 0xFF00) == 0) (g_Reg->STATUS_REGISTER & 0xFF00) == 0)
{ {
if (g_Plugins->Gfx()->UpdateScreen != NULL) if (g_Plugins->Gfx()->UpdateScreen != NULL)
{ {
g_Plugins->Gfx()->UpdateScreen(); g_Plugins->Gfx()->UpdateScreen();
} }
//CurrentFrame = 0; //CurrentFrame = 0;
//CurrentPercent = 0; //CurrentPercent = 0;
//DisplayFPS(); //DisplayFPS();
g_Notify->DisplayError(GS(MSG_PERM_LOOP)); g_Notify->DisplayError(GS(MSG_PERM_LOOP));
g_System->CloseCpu(); g_System->CloseCpu();
} }
else else
{ {
if (*g_NextTimer > 0) if (*g_NextTimer > 0)
{ {
*g_NextTimer = 0 - g_System->CountPerOp(); *g_NextTimer = 0 - g_System->CountPerOp();
g_SystemTimer->UpdateTimers(); g_SystemTimer->UpdateTimers();
} }
} }
} }
void CInterpreterCPU::ExecuteCPU() void CInterpreterCPU::ExecuteCPU()
{
bool & Done = g_System->m_EndEmulation;
uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
OPCODE & Opcode = R4300iOp::m_Opcode;
DWORD & JumpToLocation = R4300iOp::m_JumpToLocation;
bool & TestTimer = R4300iOp::m_TestTimer;
const BOOL & bDoSomething= g_SystemEvents->DoSomething();
DWORD CountPerOp = g_System->CountPerOp();
int & NextTimer = *g_NextTimer;
__try
{
while (!Done)
{
if (g_MMU->LW_VAddr(PROGRAM_COUNTER, Opcode.Hex))
{
/*if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER< 0x80380000)
{
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER));
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
}*/
m_R4300i_Opcode[ Opcode.op ]();
NextTimer -= CountPerOp;
switch (R4300iOp::m_NextInstruction)
{
case NORMAL:
PROGRAM_COUNTER += 4;
break;
case DELAY_SLOT:
R4300iOp::m_NextInstruction = JUMP;
PROGRAM_COUNTER += 4;
break;
case PERMLOOP_DO_DELAY:
R4300iOp::m_NextInstruction = PERMLOOP_DELAY_DONE;
PROGRAM_COUNTER += 4;
break;
case JUMP:
{
BOOL CheckTimer = (JumpToLocation < PROGRAM_COUNTER || TestTimer);
PROGRAM_COUNTER = JumpToLocation;
R4300iOp::m_NextInstruction = NORMAL;
if (CheckTimer)
{
TestTimer = false;
if (NextTimer < 0)
{
g_SystemTimer->TimerDone();
}
if (bDoSomething)
{
g_SystemEvents->ExecuteEvents();
}
}
}
break;
case PERMLOOP_DELAY_DONE:
PROGRAM_COUNTER = JumpToLocation;
R4300iOp::m_NextInstruction = NORMAL;
CInterpreterCPU::InPermLoop();
g_SystemTimer->TimerDone();
if (bDoSomething)
{
g_SystemEvents->ExecuteEvents();
}
break;
default:
g_Notify->BreakPoint(__FILEW__,__LINE__);
}
}
else
{
g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP,PROGRAM_COUNTER);
R4300iOp::m_NextInstruction = NORMAL;
}
}
} __except( g_MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) )
{
g_Notify->DisplayError(GS(MSG_UNKNOWN_MEM_ACTION));
ExitThread(0);
}
}
void CInterpreterCPU::ExecuteOps(int Cycles)
{ {
bool & Done = g_System->m_EndEmulation; bool & Done = g_System->m_EndEmulation;
uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER; uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
OPCODE & Opcode = R4300iOp::m_Opcode; OPCODE & Opcode = R4300iOp::m_Opcode;
DWORD & JumpToLocation = R4300iOp::m_JumpToLocation; uint32_t & JumpToLocation = R4300iOp::m_JumpToLocation;
bool & TestTimer = R4300iOp::m_TestTimer; bool & TestTimer = R4300iOp::m_TestTimer;
const BOOL & DoSomething = g_SystemEvents->DoSomething(); const int32_t & bDoSomething = g_SystemEvents->DoSomething();
DWORD CountPerOp = g_System->CountPerOp(); uint32_t CountPerOp = g_System->CountPerOp();
int32_t & NextTimer = *g_NextTimer;
__try __try
{ {
while (!Done) while (!Done)
{ {
if (Cycles <= 0) if (g_MMU->LW_VAddr(PROGRAM_COUNTER, Opcode.Hex))
{ {
g_SystemTimer->UpdateTimers(); /*if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER< 0x80380000)
return; {
} WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER));
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
if (g_MMU->LW_VAddr(PROGRAM_COUNTER, Opcode.Hex)) //WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
{ }*/
/*if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER< 0x80380000) m_R4300i_Opcode[Opcode.op]();
{ NextTimer -= CountPerOp;
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER));
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
}*/
/*if (PROGRAM_COUNTER > 0x80323000 && PROGRAM_COUNTER< 0x80380000)
{
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER));
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
}*/
m_R4300i_Opcode[ Opcode.op ]();
_GPR[0].DW = 0; /* MIPS $zero hard-wired to 0 */
Cycles -= CountPerOp; switch (R4300iOp::m_NextInstruction)
*g_NextTimer -= CountPerOp; {
case NORMAL:
/*static DWORD TestAddress = 0x80077B0C, TestValue = 0, CurrentValue = 0; PROGRAM_COUNTER += 4;
if (g_MMU->LW_VAddr(TestAddress, TestValue)) break;
{ case DELAY_SLOT:
if (TestValue != CurrentValue) R4300iOp::m_NextInstruction = JUMP;
{ PROGRAM_COUNTER += 4;
WriteTraceF(TraceError,"%X: %X changed (%s)",PROGRAM_COUNTER,TestAddress,R4300iOpcodeName(m_Opcode.Hex,PROGRAM_COUNTER) ); break;
CurrentValue = TestValue; case PERMLOOP_DO_DELAY:
} R4300iOp::m_NextInstruction = PERMLOOP_DELAY_DONE;
}*/ PROGRAM_COUNTER += 4;
break;
switch (R4300iOp::m_NextInstruction) case JUMP:
{ {
case NORMAL: bool CheckTimer = (JumpToLocation < PROGRAM_COUNTER || TestTimer);
PROGRAM_COUNTER += 4; PROGRAM_COUNTER = JumpToLocation;
break; R4300iOp::m_NextInstruction = NORMAL;
case DELAY_SLOT: if (CheckTimer)
R4300iOp::m_NextInstruction = JUMP; {
PROGRAM_COUNTER += 4; TestTimer = false;
break; if (NextTimer < 0)
case PERMLOOP_DO_DELAY: {
R4300iOp::m_NextInstruction = PERMLOOP_DELAY_DONE; g_SystemTimer->TimerDone();
PROGRAM_COUNTER += 4; }
break; if (bDoSomething)
case JUMP: {
{ g_SystemEvents->ExecuteEvents();
BOOL CheckTimer = (JumpToLocation < PROGRAM_COUNTER || TestTimer); }
PROGRAM_COUNTER = JumpToLocation; }
R4300iOp::m_NextInstruction = NORMAL; }
if (CheckTimer) break;
{ case PERMLOOP_DELAY_DONE:
TestTimer = false; PROGRAM_COUNTER = JumpToLocation;
if (*g_NextTimer < 0) R4300iOp::m_NextInstruction = NORMAL;
{ CInterpreterCPU::InPermLoop();
g_SystemTimer->TimerDone(); g_SystemTimer->TimerDone();
} if (bDoSomething)
if (DoSomething) {
{ g_SystemEvents->ExecuteEvents();
g_SystemEvents->ExecuteEvents(); }
} break;
} default:
} g_Notify->BreakPoint(__FILEW__, __LINE__);
break; }
case PERMLOOP_DELAY_DONE: }
PROGRAM_COUNTER = JumpToLocation; else
R4300iOp::m_NextInstruction = NORMAL; {
CInterpreterCPU::InPermLoop(); g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP, PROGRAM_COUNTER);
g_SystemTimer->TimerDone(); R4300iOp::m_NextInstruction = NORMAL;
if (DoSomething) }
{ }
g_SystemEvents->ExecuteEvents();
}
break;
default:
g_Notify->BreakPoint(__FILEW__,__LINE__);
}
}
else
{
g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP,PROGRAM_COUNTER);
R4300iOp::m_NextInstruction = NORMAL;
}
}
} __except( g_MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) ) } __except( g_MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) )
{ {
g_Notify->DisplayError(GS(MSG_UNKNOWN_MEM_ACTION)); g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION));
ExitThread(0); }
} }
void CInterpreterCPU::ExecuteOps(int32_t Cycles)
{
bool & Done = g_System->m_EndEmulation;
uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
OPCODE & Opcode = R4300iOp::m_Opcode;
uint32_t & JumpToLocation = R4300iOp::m_JumpToLocation;
bool & TestTimer = R4300iOp::m_TestTimer;
const int32_t & DoSomething = g_SystemEvents->DoSomething();
uint32_t CountPerOp = g_System->CountPerOp();
__try
{
while (!Done)
{
if (Cycles <= 0)
{
g_SystemTimer->UpdateTimers();
return;
}
if (g_MMU->LW_VAddr(PROGRAM_COUNTER, Opcode.Hex))
{
/*if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER< 0x80380000)
{
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER));
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
}*/
/*if (PROGRAM_COUNTER > 0x80323000 && PROGRAM_COUNTER< 0x80380000)
{
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER));
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
}*/
m_R4300i_Opcode[Opcode.op]();
_GPR[0].DW = 0; /* MIPS $zero hard-wired to 0 */
Cycles -= CountPerOp;
*g_NextTimer -= CountPerOp;
/*static uint32_t TestAddress = 0x80077B0C, TestValue = 0, CurrentValue = 0;
if (g_MMU->LW_VAddr(TestAddress, TestValue))
{
if (TestValue != CurrentValue)
{
WriteTraceF(TraceError,"%X: %X changed (%s)",PROGRAM_COUNTER,TestAddress,R4300iOpcodeName(m_Opcode.Hex,PROGRAM_COUNTER) );
CurrentValue = TestValue;
}
}*/
switch (R4300iOp::m_NextInstruction)
{
case NORMAL:
PROGRAM_COUNTER += 4;
break;
case DELAY_SLOT:
R4300iOp::m_NextInstruction = JUMP;
PROGRAM_COUNTER += 4;
break;
case PERMLOOP_DO_DELAY:
R4300iOp::m_NextInstruction = PERMLOOP_DELAY_DONE;
PROGRAM_COUNTER += 4;
break;
case JUMP:
{
bool CheckTimer = (JumpToLocation < PROGRAM_COUNTER || TestTimer);
PROGRAM_COUNTER = JumpToLocation;
R4300iOp::m_NextInstruction = NORMAL;
if (CheckTimer)
{
TestTimer = false;
if (*g_NextTimer < 0)
{
g_SystemTimer->TimerDone();
}
if (DoSomething)
{
g_SystemEvents->ExecuteEvents();
}
}
}
break;
case PERMLOOP_DELAY_DONE:
PROGRAM_COUNTER = JumpToLocation;
R4300iOp::m_NextInstruction = NORMAL;
CInterpreterCPU::InPermLoop();
g_SystemTimer->TimerDone();
if (DoSomething)
{
g_SystemEvents->ExecuteEvents();
}
break;
default:
g_Notify->BreakPoint(__FILEW__, __LINE__);
}
}
else
{
g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP, PROGRAM_COUNTER);
R4300iOp::m_NextInstruction = NORMAL;
}
}
}
__except( g_MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) )
{
g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION));
}
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,228 +11,225 @@
#pragma once #pragma once
class R4300iOp : class R4300iOp :
protected CDebugSettings, protected CDebugSettings,
protected CSystemRegisters protected CSystemRegisters
{ {
public: public:
typedef void(*Func)(); typedef void(*Func)();
/************************* OpCode functions *************************/ /************************* OpCode functions *************************/
static void J(); static void J();
static void JAL(); static void JAL();
static void BNE(); static void BNE();
static void BEQ(); static void BEQ();
static void BLEZ(); static void BLEZ();
static void BGTZ(); static void BGTZ();
static void ADDI(); static void ADDI();
static void ADDIU(); static void ADDIU();
static void SLTI(); static void SLTI();
static void SLTIU(); static void SLTIU();
static void ANDI(); static void ANDI();
static void ORI(); static void ORI();
static void XORI(); static void XORI();
static void LUI(); static void LUI();
static void BEQL(); static void BEQL();
static void BNEL(); static void BNEL();
static void BLEZL(); static void BLEZL();
static void BGTZL(); static void BGTZL();
static void DADDIU(); static void DADDIU();
static void LDL(); static void LDL();
static void LDR(); static void LDR();
static void LB(); static void LB();
static void LH(); static void LH();
static void LWL(); static void LWL();
static void LW(); static void LW();
static void LBU(); static void LBU();
static void LHU(); static void LHU();
static void LWR(); static void LWR();
static void LWU(); static void LWU();
static void SB(); static void SB();
static void SH(); static void SH();
static void SWL(); static void SWL();
static void SW(); static void SW();
static void SDL(); static void SDL();
static void SDR(); static void SDR();
static void SWR(); static void SWR();
static void CACHE(); static void CACHE();
static void LL(); static void LL();
static void LWC1(); static void LWC1();
static void LDC1(); static void LDC1();
static void LD(); static void LD();
static void SC(); static void SC();
static void SWC1(); static void SWC1();
static void SDC1(); static void SDC1();
static void SD(); static void SD();
/********************** R4300i OpCodes: Special **********************/
static void SPECIAL_SLL();
static void SPECIAL_SRL();
static void SPECIAL_SRA();
static void SPECIAL_SLLV();
static void SPECIAL_SRLV();
static void SPECIAL_SRAV();
static void SPECIAL_JR();
static void SPECIAL_JALR();
static void SPECIAL_SYSCALL();
static void SPECIAL_BREAK();
static void SPECIAL_SYNC();
static void SPECIAL_MFHI();
static void SPECIAL_MTHI();
static void SPECIAL_MFLO();
static void SPECIAL_MTLO();
static void SPECIAL_DSLLV();
static void SPECIAL_DSRLV();
static void SPECIAL_DSRAV();
static void SPECIAL_MULT();
static void SPECIAL_MULTU();
static void SPECIAL_DIV();
static void SPECIAL_DIVU();
static void SPECIAL_DMULT();
static void SPECIAL_DMULTU();
static void SPECIAL_DDIV();
static void SPECIAL_DDIVU();
static void SPECIAL_ADD();
static void SPECIAL_ADDU();
static void SPECIAL_SUB();
static void SPECIAL_SUBU();
static void SPECIAL_AND();
static void SPECIAL_OR();
static void SPECIAL_XOR();
static void SPECIAL_NOR();
static void SPECIAL_SLT();
static void SPECIAL_SLTU();
static void SPECIAL_DADD();
static void SPECIAL_DADDU();
static void SPECIAL_DSUB();
static void SPECIAL_DSUBU();
static void SPECIAL_TEQ();
static void SPECIAL_DSLL();
static void SPECIAL_DSRL();
static void SPECIAL_DSRA();
static void SPECIAL_DSLL32();
static void SPECIAL_DSRL32();
static void SPECIAL_DSRA32();
/********************** R4300i OpCodes: Special **********************/ /********************** R4300i OpCodes: RegImm **********************/
static void SPECIAL_SLL(); static void REGIMM_BLTZ();
static void SPECIAL_SRL(); static void REGIMM_BGEZ();
static void SPECIAL_SRA(); static void REGIMM_BLTZL();
static void SPECIAL_SLLV(); static void REGIMM_BGEZL();
static void SPECIAL_SRLV(); static void REGIMM_BLTZAL();
static void SPECIAL_SRAV(); static void REGIMM_BGEZAL();
static void SPECIAL_JR();
static void SPECIAL_JALR();
static void SPECIAL_SYSCALL();
static void SPECIAL_BREAK();
static void SPECIAL_SYNC();
static void SPECIAL_MFHI();
static void SPECIAL_MTHI();
static void SPECIAL_MFLO();
static void SPECIAL_MTLO();
static void SPECIAL_DSLLV();
static void SPECIAL_DSRLV();
static void SPECIAL_DSRAV();
static void SPECIAL_MULT();
static void SPECIAL_MULTU();
static void SPECIAL_DIV();
static void SPECIAL_DIVU();
static void SPECIAL_DMULT();
static void SPECIAL_DMULTU();
static void SPECIAL_DDIV();
static void SPECIAL_DDIVU();
static void SPECIAL_ADD();
static void SPECIAL_ADDU();
static void SPECIAL_SUB();
static void SPECIAL_SUBU();
static void SPECIAL_AND();
static void SPECIAL_OR();
static void SPECIAL_XOR();
static void SPECIAL_NOR();
static void SPECIAL_SLT();
static void SPECIAL_SLTU();
static void SPECIAL_DADD();
static void SPECIAL_DADDU();
static void SPECIAL_DSUB();
static void SPECIAL_DSUBU();
static void SPECIAL_TEQ();
static void SPECIAL_DSLL();
static void SPECIAL_DSRL();
static void SPECIAL_DSRA();
static void SPECIAL_DSLL32();
static void SPECIAL_DSRL32();
static void SPECIAL_DSRA32();
/********************** R4300i OpCodes: RegImm **********************/ /************************** COP0 functions **************************/
static void REGIMM_BLTZ(); static void COP0_MF();
static void REGIMM_BGEZ(); static void COP0_MT();
static void REGIMM_BLTZL();
static void REGIMM_BGEZL();
static void REGIMM_BLTZAL();
static void REGIMM_BGEZAL();
/************************** COP0 functions **************************/ /************************** COP0 CO functions ***********************/
static void COP0_MF(); static void COP0_CO_TLBR();
static void COP0_MT(); static void COP0_CO_TLBWI();
static void COP0_CO_TLBWR();
static void COP0_CO_TLBP();
static void COP0_CO_ERET();
/************************** COP0 CO functions ***********************/ /************************** COP1 functions **************************/
static void COP0_CO_TLBR(); static void COP1_MF();
static void COP0_CO_TLBWI(); static void COP1_DMF();
static void COP0_CO_TLBWR(); static void COP1_CF();
static void COP0_CO_TLBP(); static void COP1_MT();
static void COP0_CO_ERET(); static void COP1_DMT();
static void COP1_CT();
/************************** COP1 functions **************************/ /************************* COP1: BC1 functions ***********************/
static void COP1_MF(); static void COP1_BCF();
static void COP1_DMF(); static void COP1_BCT();
static void COP1_CF(); static void COP1_BCFL();
static void COP1_MT(); static void COP1_BCTL();
static void COP1_DMT();
static void COP1_CT();
/************************* COP1: BC1 functions ***********************/ /************************** COP1: S functions ************************/
static void COP1_BCF(); static void COP1_S_ADD();
static void COP1_BCT(); static void COP1_S_SUB();
static void COP1_BCFL(); static void COP1_S_MUL();
static void COP1_BCTL(); static void COP1_S_DIV();
static void COP1_S_SQRT();
static void COP1_S_ABS();
static void COP1_S_MOV();
static void COP1_S_NEG();
static void COP1_S_TRUNC_L();
static void COP1_S_CEIL_L(); //added by Witten
static void COP1_S_FLOOR_L(); //added by Witten
static void COP1_S_ROUND_W();
static void COP1_S_TRUNC_W();
static void COP1_S_CEIL_W(); //added by Witten
static void COP1_S_FLOOR_W();
static void COP1_S_CVT_D();
static void COP1_S_CVT_W();
static void COP1_S_CVT_L();
static void COP1_S_CMP();
/************************** COP1: S functions ************************/ /************************** COP1: D functions ************************/
static void COP1_S_ADD(); static void COP1_D_ADD();
static void COP1_S_SUB(); static void COP1_D_SUB();
static void COP1_S_MUL(); static void COP1_D_MUL();
static void COP1_S_DIV(); static void COP1_D_DIV();
static void COP1_S_SQRT(); static void COP1_D_SQRT();
static void COP1_S_ABS(); static void COP1_D_ABS();
static void COP1_S_MOV(); static void COP1_D_MOV();
static void COP1_S_NEG(); static void COP1_D_NEG();
static void COP1_S_TRUNC_L(); static void COP1_D_TRUNC_L(); //added by Witten
static void COP1_S_CEIL_L(); //added by Witten static void COP1_D_CEIL_L(); //added by Witten
static void COP1_S_FLOOR_L(); //added by Witten static void COP1_D_FLOOR_L(); //added by Witten
static void COP1_S_ROUND_W(); static void COP1_D_ROUND_W();
static void COP1_S_TRUNC_W(); static void COP1_D_TRUNC_W();
static void COP1_S_CEIL_W(); //added by Witten static void COP1_D_CEIL_W(); //added by Witten
static void COP1_S_FLOOR_W(); static void COP1_D_FLOOR_W(); //added by Witten
static void COP1_S_CVT_D(); static void COP1_D_CVT_S();
static void COP1_S_CVT_W(); static void COP1_D_CVT_W();
static void COP1_S_CVT_L(); static void COP1_D_CVT_L();
static void COP1_S_CMP(); static void COP1_D_CMP();
/************************** COP1: D functions ************************/ /************************** COP1: W functions ************************/
static void COP1_D_ADD(); static void COP1_W_CVT_S();
static void COP1_D_SUB(); static void COP1_W_CVT_D();
static void COP1_D_MUL();
static void COP1_D_DIV();
static void COP1_D_SQRT();
static void COP1_D_ABS();
static void COP1_D_MOV();
static void COP1_D_NEG();
static void COP1_D_TRUNC_L(); //added by Witten
static void COP1_D_CEIL_L(); //added by Witten
static void COP1_D_FLOOR_L(); //added by Witten
static void COP1_D_ROUND_W();
static void COP1_D_TRUNC_W();
static void COP1_D_CEIL_W(); //added by Witten
static void COP1_D_FLOOR_W(); //added by Witten
static void COP1_D_CVT_S();
static void COP1_D_CVT_W();
static void COP1_D_CVT_L();
static void COP1_D_CMP();
/************************** COP1: W functions ************************/ /************************** COP1: L functions ************************/
static void COP1_W_CVT_S(); static void COP1_L_CVT_S();
static void COP1_W_CVT_D(); static void COP1_L_CVT_D();
/************************** COP1: L functions ************************/ /************************** Other functions **************************/
static void COP1_L_CVT_S(); static void UnknownOpcode();
static void COP1_L_CVT_D();
/************************** Other functions **************************/ static Func* BuildInterpreter();
static void UnknownOpcode();
static bool m_TestTimer;
static Func* BuildInterpreter(); static uint32_t m_NextInstruction;
static OPCODE m_Opcode;
static bool m_TestTimer; static uint32_t m_JumpToLocation;
static DWORD m_NextInstruction;
static OPCODE m_Opcode;
static DWORD m_JumpToLocation;
protected: protected:
static void SPECIAL(); static void SPECIAL();
static void REGIMM(); static void REGIMM();
static void COP0(); static void COP0();
static void COP0_CO(); static void COP0_CO();
static void COP1(); static void COP1();
static void COP1_BC(); static void COP1_BC();
static void COP1_S(); static void COP1_S();
static void COP1_D(); static void COP1_D();
static void COP1_W(); static void COP1_W();
static void COP1_L(); static void COP1_L();
static Func Jump_Opcode[64]; static Func Jump_Opcode[64];
static Func Jump_Special[64]; static Func Jump_Special[64];
static Func Jump_Regimm[32]; static Func Jump_Regimm[32];
static Func Jump_CoP0[32]; static Func Jump_CoP0[32];
static Func Jump_CoP0_Function[64]; static Func Jump_CoP0_Function[64];
static Func Jump_CoP1[32]; static Func Jump_CoP1[32];
static Func Jump_CoP1_BC[32]; static Func Jump_CoP1_BC[32];
static Func Jump_CoP1_S[64]; static Func Jump_CoP1_S[64];
static Func Jump_CoP1_D[64]; static Func Jump_CoP1_D[64];
static Func Jump_CoP1_W[64]; static Func Jump_CoP1_W[64];
static Func Jump_CoP1_L[64]; static Func Jump_CoP1_L[64];
static const DWORD SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
static const int SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];
static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];
}; };

View File

@ -10,7 +10,7 @@
****************************************************************************/ ****************************************************************************/
#include "stdafx.h" #include "stdafx.h"
bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2); bool DelaySlotEffectsCompare (uint32_t PC, uint32_t Reg1, uint32_t Reg2);
CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos) : CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos) :
m_VAddrEnter(VAddrEnter), m_VAddrEnter(VAddrEnter),

View File

@ -12,7 +12,7 @@
void InPermLoop(); void InPermLoop();
bool DelaySlotEffectsCompare(DWORD PC, DWORD Reg1, DWORD Reg2); bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
static bool DelaySlotEffectsJump(DWORD JumpPC) { static bool DelaySlotEffectsJump(DWORD JumpPC) {
OPCODE Command; OPCODE Command;

View File

@ -14,7 +14,7 @@
#define CHECKED_BUILD 1 #define CHECKED_BUILD 1
#endif #endif
bool DelaySlotEffectsCompare ( DWORD PC, DWORD Reg1, DWORD Reg2 ); bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
LoopAnalysis::LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section) : LoopAnalysis::LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section) :
m_EnterSection(Section), m_EnterSection(Section),

View File

@ -38,7 +38,7 @@ void CRecompilerOps::CompileWriteTLBMiss (x86Reg AddressReg, x86Reg LookUpReg )
m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBWriteMiss, false, JeLabel32); m_Section->CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBWriteMiss, false, JeLabel32);
} }
bool DelaySlotEffectsCompare ( DWORD PC, DWORD Reg1, DWORD Reg2 ); bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
/************************** Branch functions ************************/ /************************** Branch functions ************************/
void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link) void CRecompilerOps::Compile_Branch (CRecompilerOps::BranchFunction CompareFunc, BRANCH_TYPE BranchType, bool Link)