aboutsummaryrefslogtreecommitdiff
path: root/src/ARM.cpp
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2020-07-01 00:01:11 +0200
committerGitHub <noreply@github.com>2020-07-01 00:01:11 +0200
commit62c6e2f703d88660e0ca9bda78032c5bd6b63a78 (patch)
tree1dbf9eb1bbe418d14f07dc3a0e30821fb5deb258 /src/ARM.cpp
parentd97ce22b010e868437c649911bce89d679a4deaa (diff)
parentc5381d2911d47fb1fcbd6ec27a83f5da3606c4bd (diff)
Merge pull request #667 from Arisotura/generic_jit
merge jit
Diffstat (limited to 'src/ARM.cpp')
-rw-r--r--src/ARM.cpp250
1 files changed, 237 insertions, 13 deletions
diff --git a/src/ARM.cpp b/src/ARM.cpp
index 68cac59..8530795 100644
--- a/src/ARM.cpp
+++ b/src/ARM.cpp
@@ -21,8 +21,15 @@
#include "DSi.h"
#include "ARM.h"
#include "ARMInterpreter.h"
+#include "Config.h"
#include "AREngine.h"
+#include "ARMJIT.h"
+#include "Config.h"
+#ifdef JIT_ENABLED
+#include "ARMJIT.h"
+#include "ARMJIT_Memory.h"
+#endif
// instruction timing notes
//
@@ -72,7 +79,9 @@ ARM::~ARM()
ARMv5::ARMv5() : ARM(0)
{
- //
+#ifndef JIT_ENABLED
+ DTCM = new u8[DTCMSize];
+#endif
}
ARMv4::ARMv4() : ARM(1)
@@ -80,6 +89,13 @@ ARMv4::ARMv4() : ARM(1)
//
}
+ARMv5::~ARMv5()
+{
+#ifndef JIT_ENABLED
+ delete[] DTCM;
+#endif
+}
+
void ARM::Reset()
{
Cycles = 0;
@@ -96,6 +112,12 @@ void ARM::Reset()
CodeMem.Mem = NULL;
+#ifdef JIT_ENABLED
+ FastBlockLookup = NULL;
+ FastBlockLookupStart = 0;
+ FastBlockLookupSize = 0;
+#endif
+
// zorp
JumpTo(ExceptionBase);
}
@@ -123,7 +145,6 @@ void ARMv5::Reset()
GetMemRegion = NDS::ARM9GetMemRegion;
}
- CP15Reset();
ARM::Reset();
}
@@ -158,7 +179,11 @@ void ARM::DoSavestate(Savestate* file)
file->Var32((u32*)&Cycles);
//file->Var32((u32*)&CyclesToRun);
- file->Var32(&Halted);
+
+ // hack to make save states compatible
+ u32 halted = Halted;
+ file->Var32(&halted);
+ Halted = halted;
file->VarArray(R, 16*sizeof(u32));
file->Var32(&CPSR);
@@ -168,6 +193,15 @@ void ARM::DoSavestate(Savestate* file)
file->VarArray(R_IRQ, 3*sizeof(u32));
file->VarArray(R_UND, 3*sizeof(u32));
file->Var32(&CurInstr);
+#ifdef JIT_ENABLED
+ if (!file->Saving && Config::JIT_Enable)
+ {
+ // hack, the JIT doesn't really pipeline
+ // but we still want JIT save states to be
+ // loaded while running the interpreter
+ FillPipeline();
+ }
+#endif
file->VarArray(NextInstr, 2*sizeof(u32));
file->Var32(&ExceptionBase);
@@ -240,15 +274,15 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
if (addr & 0x2)
{
NextInstr[0] = CodeRead32(addr-2, true) >> 16;
- Cycles += CodeCycles;
+ Cycles -= CodeCycles;
NextInstr[1] = CodeRead32(addr+2, false);
- Cycles += CodeCycles;
+ Cycles -= CodeCycles;
}
else
{
NextInstr[0] = CodeRead32(addr, true);
NextInstr[1] = NextInstr[0] >> 16;
- Cycles += CodeCycles;
+ Cycles -= CodeCycles;
}
CPSR |= 0x20;
@@ -261,9 +295,9 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
if (newregion != oldregion) SetupCodeMem(addr);
NextInstr[0] = CodeRead32(addr, true);
- Cycles += CodeCycles;
+ Cycles -= CodeCycles;
NextInstr[1] = CodeRead32(addr+4, false);
- Cycles += CodeCycles;
+ Cycles -= CodeCycles;
CPSR &= ~0x20;
}
@@ -303,7 +337,7 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr)
NextInstr[0] = CodeRead16(addr);
NextInstr[1] = CodeRead16(addr+2);
- Cycles += NDS::ARM7MemTimings[CodeCycles][0] + NDS::ARM7MemTimings[CodeCycles][1];
+ Cycles -= NDS::ARM7MemTimings[CodeCycles][0] + NDS::ARM7MemTimings[CodeCycles][1];
CPSR |= 0x20;
}
@@ -316,7 +350,7 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr)
NextInstr[0] = CodeRead32(addr);
NextInstr[1] = CodeRead32(addr+4);
- Cycles += NDS::ARM7MemTimings[CodeCycles][2] + NDS::ARM7MemTimings[CodeCycles][3];
+ Cycles -= NDS::ARM7MemTimings[CodeCycles][2] + NDS::ARM7MemTimings[CodeCycles][3];
CPSR &= ~0x20;
}
@@ -558,7 +592,7 @@ void ARMv5::Execute()
else
AddCycles_C();
}
-
+
// TODO optimize this shit!!!
if (Halted)
{
@@ -575,7 +609,7 @@ void ARMv5::Execute()
}*/
if (IRQ) TriggerIRQ();
- NDS::ARM9Timestamp += Cycles;
+ NDS::ARM9Timestamp -= Cycles;
Cycles = 0;
}
@@ -583,6 +617,75 @@ void ARMv5::Execute()
Halted = 0;
}
+#ifdef JIT_ENABLED
+void ARMv5::ExecuteJIT()
+{
+ if (Halted)
+ {
+ if (Halted == 2)
+ {
+ Halted = 0;
+ }
+ else if (NDS::HaltInterrupted(0))
+ {
+ Halted = 0;
+ if (NDS::IME[0] & 0x1)
+ TriggerIRQ();
+ }
+ else
+ {
+ NDS::ARM9Timestamp = NDS::ARM9Target;
+ return;
+ }
+ }
+
+ while (NDS::ARM9Timestamp < NDS::ARM9Target)
+ {
+ u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);
+
+ // hack so Cycles <= 0 becomes Cycles < 0
+ Cycles = NDS::ARM9Target - NDS::ARM9Timestamp - 1;
+
+ if ((instrAddr < FastBlockLookupStart || instrAddr >= (FastBlockLookupStart + FastBlockLookupSize))
+ && !ARMJIT::SetupExecutableRegion(0, instrAddr, FastBlockLookup, FastBlockLookupStart, FastBlockLookupSize))
+ {
+ NDS::ARM9Timestamp = NDS::ARM9Target;
+ printf("ARMv5 PC in non executable region %08X\n", R[15]);
+ return;
+ }
+
+ ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlock(0, FastBlockLookup,
+ instrAddr - FastBlockLookupStart, instrAddr);
+ if (block)
+ ARM_Dispatch(this, block);
+ else
+ ARMJIT::CompileBlock(this);
+
+ NDS::ARM9Timestamp = NDS::ARM9Target - Cycles - 1;
+
+ if (StopExecution)
+ {
+ if (IRQ)
+ TriggerIRQ();
+
+ if (Halted || IdleLoop)
+ {
+ bool idleLoop = IdleLoop;
+ IdleLoop = 0;
+ if ((Halted == 1 || idleLoop) && NDS::ARM9Timestamp < NDS::ARM9Target)
+ {
+ NDS::ARM9Timestamp = NDS::ARM9Target;
+ }
+ break;
+ }
+ }
+ }
+
+ if (Halted == 2)
+ Halted = 0;
+}
+#endif
+
void ARMv4::Execute()
{
if (Halted)
@@ -652,10 +755,131 @@ void ARMv4::Execute()
}*/
if (IRQ) TriggerIRQ();
- NDS::ARM7Timestamp += Cycles;
+ NDS::ARM7Timestamp -= Cycles;
Cycles = 0;
}
if (Halted == 2)
Halted = 0;
+
+ if (Halted == 4)
+ {
+ DSi::SoftReset();
+ Halted = 2;
+ }
+}
+
+#ifdef JIT_ENABLED
+void ARMv4::ExecuteJIT()
+{
+ if (Halted)
+ {
+ if (Halted == 2)
+ {
+ Halted = 0;
+ }
+ else if (NDS::HaltInterrupted(1))
+ {
+ Halted = 0;
+ if (NDS::IME[1] & 0x1)
+ TriggerIRQ();
+ }
+ else
+ {
+ NDS::ARM7Timestamp = NDS::ARM7Target;
+ return;
+ }
+ }
+
+ while (NDS::ARM7Timestamp < NDS::ARM7Target)
+ {
+ u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);
+
+ Cycles = NDS::ARM7Target - NDS::ARM7Timestamp - 1;
+
+ if ((instrAddr < FastBlockLookupStart || instrAddr >= (FastBlockLookupStart + FastBlockLookupSize))
+ && !ARMJIT::SetupExecutableRegion(1, instrAddr, FastBlockLookup, FastBlockLookupStart, FastBlockLookupSize))
+ {
+ NDS::ARM7Timestamp = NDS::ARM7Target;
+ printf("ARMv4 PC in non executable region %08X\n", R[15]);
+ return;
+ }
+
+ ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlock(1, FastBlockLookup,
+ instrAddr - FastBlockLookupStart, instrAddr);
+ if (block)
+ ARM_Dispatch(this, block);
+ else
+ ARMJIT::CompileBlock(this);
+
+ NDS::ARM7Timestamp = NDS::ARM7Target - Cycles - 1;
+
+ // TODO optimize this shit!!!
+ if (StopExecution)
+ {
+ if (IRQ)
+ TriggerIRQ();
+
+ if (Halted || IdleLoop)
+ {
+ bool idleLoop = IdleLoop;
+ IdleLoop = 0;
+ if ((Halted == 1 || idleLoop) && NDS::ARM7Timestamp < NDS::ARM7Target)
+ {
+ NDS::ARM7Timestamp = NDS::ARM7Target;
+ }
+ break;
+ }
+ }
+ }
+
+ if (Halted == 2)
+ Halted = 0;
+
+ if (Halted == 4)
+ {
+ DSi::SoftReset();
+ Halted = 2;
+ }
+}
+#endif
+
+void ARMv5::FillPipeline()
+{
+ SetupCodeMem(R[15]);
+
+ if (CPSR & 0x20)
+ {
+ if ((R[15] - 2) & 0x2)
+ {
+ NextInstr[0] = CodeRead32(R[15] - 4, false) >> 16;
+ NextInstr[1] = CodeRead32(R[15], false);
+ }
+ else
+ {
+ NextInstr[0] = CodeRead32(R[15] - 2, false);
+ NextInstr[1] = NextInstr[0] >> 16;
+ }
+ }
+ else
+ {
+ NextInstr[0] = CodeRead32(R[15] - 4, false);
+ NextInstr[1] = CodeRead32(R[15], false);
+ }
}
+
+void ARMv4::FillPipeline()
+{
+ SetupCodeMem(R[15]);
+
+ if (CPSR & 0x20)
+ {
+ NextInstr[0] = CodeRead16(R[15] - 2);
+ NextInstr[1] = CodeRead16(R[15]);
+ }
+ else
+ {
+ NextInstr[0] = CodeRead32(R[15] - 4);
+ NextInstr[1] = CodeRead32(R[15]);
+ }
+} \ No newline at end of file