summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Hoffman <godisgovernment@gmail.com>2009-03-23 08:49:17 +0000
committerShawn Hoffman <godisgovernment@gmail.com>2009-03-23 08:49:17 +0000
commitfc582ea56078b2cd83d24acab4e3d629d4ee40a3 (patch)
treeb6b03a0e6142a11cbbd3e1f496b0ba2bcb7ebe7d
parent32b983ef8393bb0cab4d159a0c31def426a8922c (diff)
revert this for now, i need to read more
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2739 8ced0084-cf51-0410-be5f-012b33b47a6e
-rw-r--r--Source/Core/Core/Src/PowerPC/PowerPC.cpp464
1 files changed, 223 insertions, 241 deletions
diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp
index 2a041f031c..35fd413aed 100644
--- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp
+++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp
@@ -35,298 +35,280 @@
namespace PowerPC
{
-// STATE_TO_SAVE
-PowerPCState GC_ALIGNED16(ppcState);
-volatile CPUState state = CPU_STEPPING;
+ // STATE_TO_SAVE
+ PowerPCState GC_ALIGNED16(ppcState);
+ volatile CPUState state = CPU_STEPPING;
-static CoreMode mode;
+ static CoreMode mode;
-void CompactCR()
-{
- ppcState.cr = 0;
- for (int i = 0; i < 8; i++) {
- ppcState.cr |= ppcState.cr_fast[i] << (28 - i * 4);
+ void CompactCR()
+ {
+ ppcState.cr = 0;
+ for (int i = 0; i < 8; i++) {
+ ppcState.cr |= ppcState.cr_fast[i] << (28 - i * 4);
+ }
}
-}
-void ExpandCR()
-{
- for (int i = 0; i < 8; i++) {
- ppcState.cr_fast[i] = (ppcState.cr >> (28 - i * 4)) & 0xF;
+ void ExpandCR()
+ {
+ for (int i = 0; i < 8; i++) {
+ ppcState.cr_fast[i] = (ppcState.cr >> (28 - i * 4)) & 0xF;
+ }
}
-}
-
-void DoState(PointerWrap &p)
-{
- p.Do(ppcState);
-}
-void ResetRegisters()
-{
- for (int i = 0; i < 32; i++)
+ void DoState(PointerWrap &p)
{
- ppcState.gpr[i] = 0;
- riPS0(i) = 0;
- riPS1(i) = 0;
+ p.Do(ppcState);
}
- memset(ppcState.spr, 0, sizeof(ppcState.spr));
+ void ResetRegisters()
+ {
+ for (int i = 0; i < 32; i++)
+ {
+ ppcState.gpr[i] = 0;
+ riPS0(i) = 0;
+ riPS1(i) = 0;
+ }
- ppcState.cr = 0;
- ppcState.fpscr = 0;
- ppcState.pc = 0;
- ppcState.npc = 0;
- ppcState.Exceptions = 0;
+ memset(ppcState.spr, 0, sizeof(ppcState.spr));
- TL = 0;
- TU = 0;
+ ppcState.cr = 0;
+ ppcState.fpscr = 0;
+ ppcState.pc = 0;
+ ppcState.npc = 0;
+ ppcState.Exceptions = 0;
- ppcState.msr = 0;
- rDEC = 0xFFFFFFFF;
-}
+ TL = 0;
+ TU = 0;
-void Init()
-{
- enum {
- FPU_PREC_24 = 0 << 8,
- FPU_PREC_53 = 2 << 8,
- FPU_PREC_64 = 3 << 8,
- FPU_PREC_MASK = 3 << 8,
- };
- #ifdef _M_IX86
- // sets the floating-point lib to 53-bit
- // PowerPC has a 53bit floating pipeline only
- // eg: sscanf is very sensitive
+ ppcState.msr = 0;
+ rDEC = 0xFFFFFFFF;
+ }
+
+ void Init()
+ {
+ enum {
+ FPU_PREC_24 = 0 << 8,
+ FPU_PREC_53 = 2 << 8,
+ FPU_PREC_64 = 3 << 8,
+ FPU_PREC_MASK = 3 << 8,
+ };
+#ifdef _M_IX86
+ // sets the floating-point lib to 53-bit
+ // PowerPC has a 53bit floating pipeline only
+ // eg: sscanf is very sensitive
#ifdef _WIN32
- _control87(_PC_53, MCW_PC);
+ _control87(_PC_53, MCW_PC);
#else
- unsigned short _mode;
- asm ("fstcw %0" : : "m" (_mode));
- _mode = (_mode & ~FPU_PREC_MASK) | FPU_PREC_53;
- asm ("fldcw %0" : : "m" (_mode));
+ unsigned short _mode;
+ asm ("fstcw %0" : : "m" (_mode));
+ _mode = (_mode & ~FPU_PREC_MASK) | FPU_PREC_53;
+ asm ("fldcw %0" : : "m" (_mode));
#endif
#else
- //x64 doesn't need this - fpu is done with SSE
- //but still - set any useful sse options here
+ //x64 doesn't need this - fpu is done with SSE
+ //but still - set any useful sse options here
#endif
- ResetRegisters();
- PPCTables::InitTables();
+ ResetRegisters();
+ PPCTables::InitTables();
- // Initialize both execution engines ...
- Interpreter::Init();
- jit.Init();
- // ... but start as interpreter by default.
- mode = MODE_INTERPRETER;
- state = CPU_STEPPING;
-}
-
-void Shutdown()
-{
- // Shutdown both execution engines. Doesn't matter which one is active.
- jit.Shutdown();
- Interpreter::Shutdown();
-}
+ // Initialize both execution engines ...
+ Interpreter::Init();
+ jit.Init();
+ // ... but start as interpreter by default.
+ mode = MODE_INTERPRETER;
+ state = CPU_STEPPING;
+ }
-void SetMode(CoreMode new_mode)
-{
- if (new_mode == mode)
- return; // We don't need to do anything.
+ void Shutdown()
+ {
+ // Shutdown both execution engines. Doesn't matter which one is active.
+ jit.Shutdown();
+ Interpreter::Shutdown();
+ }
- mode = new_mode;
- switch (mode)
+ void SetMode(CoreMode new_mode)
{
- case MODE_INTERPRETER: // Switching from JIT to interpreter
- jit.ClearCache(); // Remove all those nasty JIT patches.
- break;
+ if (new_mode == mode)
+ return; // We don't need to do anything.
- case MODE_JIT: // Switching from interpreter to JIT.
- // Don't really need to do much. It'll work, the cache will refill itself.
- break;
+ mode = new_mode;
+ switch (mode)
+ {
+ case MODE_INTERPRETER: // Switching from JIT to interpreter
+ jit.ClearCache(); // Remove all those nasty JIT patches.
+ break;
+
+ case MODE_JIT: // Switching from interpreter to JIT.
+ // Don't really need to do much. It'll work, the cache will refill itself.
+ break;
+ }
}
-}
-void SingleStep()
-{
- switch (mode)
+ void SingleStep()
{
- case MODE_INTERPRETER:
- Interpreter::SingleStep();
- break;
- case MODE_JIT:
- jit.SingleStep();
- break;
+ switch (mode)
+ {
+ case MODE_INTERPRETER:
+ Interpreter::SingleStep();
+ break;
+ case MODE_JIT:
+ jit.SingleStep();
+ break;
+ }
}
-}
-void RunLoop()
-{
- state = CPU_RUNNING;
- switch (mode)
+ void RunLoop()
{
- case MODE_INTERPRETER:
- Interpreter::Run();
- break;
- case MODE_JIT:
- jit.Run();
- break;
+ state = CPU_RUNNING;
+ switch (mode)
+ {
+ case MODE_INTERPRETER:
+ Interpreter::Run();
+ break;
+ case MODE_JIT:
+ jit.Run();
+ break;
+ }
+ Host_UpdateDisasmDialog();
}
- Host_UpdateDisasmDialog();
-}
-
-CPUState GetState()
-{
- return state;
-}
-
-volatile CPUState *GetStatePtr()
-{
- return &state;
-}
-void Start()
-{
- state = CPU_RUNNING;
- Host_UpdateDisasmDialog();
-}
+ CPUState GetState()
+ {
+ return state;
+ }
-void Pause()
-{
- state = CPU_STEPPING;
- Host_UpdateDisasmDialog();
-}
+ volatile CPUState *GetStatePtr()
+ {
+ return &state;
+ }
-void Stop()
-{
- state = CPU_POWERDOWN;
- Host_UpdateDisasmDialog();
-}
+ void Start()
+ {
+ state = CPU_RUNNING;
+ Host_UpdateDisasmDialog();
+ }
-void CheckExceptions()
-{
- // This check is unnecessary in JIT mode. However, it probably doesn't really hurt.
- if (!ppcState.Exceptions)
- return;
+ void Pause()
+ {
+ state = CPU_STEPPING;
+ Host_UpdateDisasmDialog();
+ }
- // TODO(ector):
- // gcemu uses the mask 0x87C0FFFF instead of 0x0780FF77
- // Investigate!
+ void Stop()
+ {
+ state = CPU_POWERDOWN;
+ Host_UpdateDisasmDialog();
+ }
- // EXTERNAL INTTERUPT
- if (MSR & 0x0008000)
+ void CheckExceptions()
{
- // EXCEPTION_SYSRESET (hard)
- // EXCEPTION_MACHINE_CHECK
- // EXCEPTION_SYSRESET (soft)
- if (ppcState.Exceptions & EXCEPTION_EXTERNAL_INT)
+ // This check is unnecessary in JIT mode. However, it probably doesn't really hurt.
+ if (!ppcState.Exceptions)
+ return;
+
+ // TODO(ector):
+ // gcemu uses the mask 0x87C0FFFF instead of 0x0780FF77
+ // Investigate!
+
+ if (ppcState.Exceptions & EXCEPTION_FPU_UNAVAILABLE)
+ {
+ //This happens a lot - Gamecube OS uses deferred FPU context switching
+ SRR0 = PC; // re-execute the instruction
+ SRR1 = MSR & 0x0780FF77;
+ NPC = 0x80000800;
+
+ INFO_LOG(GEKKO, "EXCEPTION_FPU_UNAVAILABLE");
+ ppcState.Exceptions &= ~EXCEPTION_FPU_UNAVAILABLE;
+ SRR1 |= 0x02; //recoverable
+ }
+ else if (ppcState.Exceptions & EXCEPTION_SYSCALL)
+ {
+ SRR0 = NPC; // execute next instruction when we come back from handler
+ SRR1 = MSR & 0x0780FF77;
+ NPC = 0x80000C00;
+
+ INFO_LOG(GEKKO, "EXCEPTION_SYSCALL (PC=%08x)", PC);
+ ppcState.Exceptions &= ~EXCEPTION_SYSCALL;
+ SRR1 |= 0x02; //recoverable
+ }
+ else if (ppcState.Exceptions & EXCEPTION_DSI)
{
- // Pokemon gets this "too early", it hasn't a handler yet
- ppcState.Exceptions &= ~EXCEPTION_EXTERNAL_INT; // clear exception
-
- SRR0 = NPC;
- NPC = 0x80000500;
- SRR1 = (MSR & 0x0780FF77);
+ SRR0 = PC; // re-execute the instruction
+ SRR1 = MSR & 0x0780FF77;
+ NPC = 0x80000300;
- INFO_LOG(GEKKO, "EXCEPTION_EXTERNAL_INT");
+ INFO_LOG(GEKKO, "EXCEPTION_DSI");
+ ppcState.Exceptions &= ~EXCEPTION_DSI;
+ //SRR1 |= 0x02; //make recoverable ?
+ }
+ else if (ppcState.Exceptions & EXCEPTION_ISI)
+ {
+ SRR0 = PC;
+ SRR1 = (MSR & 0x0780FF77) | 0x40000000;
+ NPC = 0x80000400;
- SRR1 |= 0x02; //set it to recoverable
- _dbg_assert_msg_(GEKKO, (SRR1 & 0x02) != 0, "GEKKO", "EXTERNAL_INT unrecoverable???"); // unrecoverable exception !?!
+ INFO_LOG(GEKKO, "EXCEPTION_ISI");
+ ppcState.Exceptions &= ~EXCEPTION_ISI;
+ //SRR1 |= 0x02; //make recoverable ?
}
- // EXCEPTION_PERF_MONITOR
- else if (ppcState.Exceptions & EXCEPTION_DECREMENTER)
+ else if (ppcState.Exceptions & EXCEPTION_ALIGNMENT)
{
+ //This never happens ATM
SRR0 = NPC;
- SRR1 = MSR & 0x0000FF77;
- NPC = 0x80000900;
+ SRR1 = MSR & 0x0780FF77;
+ NPC = 0x80000600;
- ppcState.Exceptions &= ~EXCEPTION_DECREMENTER;
-
- INFO_LOG(GEKKO, "EXCEPTION_DECREMENTER");
- SRR1 |= 0x02; //make recoverable
+ INFO_LOG(GEKKO, "EXCEPTION_ALIGNMENT");
+ ppcState.Exceptions &= ~EXCEPTION_ALIGNMENT;
+ //SRR1 |= 0x02; //make recoverable ?
}
- else
+
+ // EXTERNAL INTTERUPT
+ else if (MSR & 0x0008000)
{
- _dbg_assert_msg_(GEKKO, 0, "Unknown EXT interrupt: Exceptions == %08x", ppcState.Exceptions);
- ERROR_LOG(GEKKO, "Unknown EXTERNAL INTERRUPT exception: Exceptions == %08x", ppcState.Exceptions);
+ if (ppcState.Exceptions & EXCEPTION_EXTERNAL_INT)
+ {
+ // Pokemon gets this "too early", it hasn't a handler yet
+ ppcState.Exceptions &= ~EXCEPTION_EXTERNAL_INT; // clear exception
+
+ SRR0 = NPC;
+ NPC = 0x80000500;
+ SRR1 = (MSR & 0x0780FF77);
+
+ INFO_LOG(GEKKO, "EXCEPTION_EXTERNAL_INT");
+
+ SRR1 |= 0x02; //set it to recoverable
+ _dbg_assert_msg_(GEKKO, (SRR1 & 0x02) != 0, "GEKKO", "EXTERNAL_INT unrecoverable???"); // unrecoverable exception !?!
+ }
+ else if (ppcState.Exceptions & EXCEPTION_DECREMENTER)
+ {
+ SRR0 = NPC;
+ SRR1 = MSR & 0x0000FF77;
+ NPC = 0x80000900;
+
+ ppcState.Exceptions &= ~EXCEPTION_DECREMENTER;
+
+ INFO_LOG(GEKKO, "EXCEPTION_DECREMENTER");
+ SRR1 |= 0x02; //make recoverable
+ }
+ else
+ {
+ _dbg_assert_msg_(GEKKO, 0, "Unknown EXT interrupt: Exceptions == %08x", ppcState.Exceptions);
+ ERROR_LOG(GEKKO, "Unknown EXTERNAL INTERRUPT exception: Exceptions == %08x", ppcState.Exceptions);
+ }
}
+ MSR &= ~0x0008000; // clear EE-bit so interrupts aren't possible anymore
}
- else if (ppcState.Exceptions & EXCEPTION_ISI)
- {
- SRR0 = PC;
- SRR1 = (MSR & 0x0780FF77) | 0x40000000;
- NPC = 0x80000400;
- INFO_LOG(GEKKO, "EXCEPTION_ISI");
- ppcState.Exceptions &= ~EXCEPTION_ISI;
- //SRR1 |= 0x02; //make recoverable ?
- }
- // EXCEPTION_ADDR_BREAKPOINT
- else if (ppcState.Exceptions & EXCEPTION_PROGRAM)
+ void OnIdle(u32 _uThreadAddr)
{
- SRR0 = NPC; // execute next instruction when we come back from handler
- SRR1 = MSR & 0x0780FF77;
- NPC = 0x80000700;
-
- INFO_LOG(GEKKO, "EXCEPTION_PROGRAM (PC=%08x)", PC);
- ppcState.Exceptions &= ~EXCEPTION_PROGRAM;
- SRR1 |= 0x02; //recoverable
- }
- else if (ppcState.Exceptions & EXCEPTION_SYSCALL)
- {
- SRR0 = NPC; // execute next instruction when we come back from handler
- SRR1 = MSR & 0x0780FF77;
- NPC = 0x80000C00;
-
- INFO_LOG(GEKKO, "EXCEPTION_SYSCALL (PC=%08x)", PC);
- ppcState.Exceptions &= ~EXCEPTION_SYSCALL;
- SRR1 |= 0x02; //recoverable
+ u32 nextThread = Memory::Read_U32(_uThreadAddr);
+ //do idle skipping
+ if (nextThread == 0)
+ CoreTiming::Idle();
}
- else if (ppcState.Exceptions & EXCEPTION_FPU_UNAVAILABLE)
- {
- //This happens a lot - Gamecube OS uses deferred FPU context switching
- SRR0 = PC; // re-execute the instruction
- SRR1 = MSR & 0x0780FF77;
- NPC = 0x80000800;
-
- INFO_LOG(GEKKO, "EXCEPTION_FPU_UNAVAILABLE");
- ppcState.Exceptions &= ~EXCEPTION_FPU_UNAVAILABLE;
- SRR1 |= 0x02; //recoverable
- }
- // EXCEPTION_PROGRAM (floating point)
- else if (ppcState.Exceptions & EXCEPTION_DSI)
- {
- SRR0 = PC; // re-execute the instruction
- SRR1 = MSR & 0x0780FF77;
- NPC = 0x80000300;
-
- INFO_LOG(GEKKO, "EXCEPTION_DSI");
- ppcState.Exceptions &= ~EXCEPTION_DSI;
- //SRR1 |= 0x02; //make recoverable ?
- }
- else if (ppcState.Exceptions & EXCEPTION_ALIGNMENT)
- {
- // Alignment exceptions have priorities
- //This never happens ATM
- SRR0 = NPC;
- SRR1 = MSR & 0x0780FF77;
- NPC = 0x80000600;
-
- INFO_LOG(GEKKO, "EXCEPTION_ALIGNMENT");
- ppcState.Exceptions &= ~EXCEPTION_ALIGNMENT;
- //SRR1 |= 0x02; //make recoverable ?
- }
- // Other DSI exceptions
- // EXCEPTION_TRACE
- MSR &= ~0x0008000; // clear EE-bit so interrupts aren't possible anymore
-}
-
-void OnIdle(u32 _uThreadAddr)
-{
- u32 nextThread = Memory::Read_U32(_uThreadAddr);
- //do idle skipping
- if (nextThread == 0)
- CoreTiming::Idle();
-}
-} // namespace
+} // namespace \ No newline at end of file