jit: make everything configurable
This commit is contained in:
parent
0ff79ea2ad
commit
d13d625f73
125
src/ARM.cpp
125
src/ARM.cpp
|
@ -532,7 +532,7 @@ void ARMv5::Execute()
|
||||||
|
|
||||||
while (NDS::ARM9Timestamp < NDS::ARM9Target)
|
while (NDS::ARM9Timestamp < NDS::ARM9Target)
|
||||||
{
|
{
|
||||||
/*if (CPSR & 0x20) // THUMB
|
if (CPSR & 0x20) // THUMB
|
||||||
{
|
{
|
||||||
// prefetch
|
// prefetch
|
||||||
R[15] += 2;
|
R[15] += 2;
|
||||||
|
@ -565,13 +565,7 @@ void ARMv5::Execute()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
AddCycles_C();
|
AddCycles_C();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
/*if (!ARMJIT::IsMapped(0, R[15] - ((CPSR&0x20)?2:4)))
|
|
||||||
printf("aaarg ungempappter raum %x\n", R[15]);*/
|
|
||||||
|
|
||||||
ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock(0, R[15] - ((CPSR&0x20)?2:4));
|
|
||||||
Cycles += (block ? block : ARMJIT::CompileBlock(this))();
|
|
||||||
|
|
||||||
// TODO optimize this shit!!!
|
// TODO optimize this shit!!!
|
||||||
if (Halted)
|
if (Halted)
|
||||||
|
@ -597,6 +591,58 @@ void ARMv5::Execute()
|
||||||
Halted = 0;
|
Halted = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (!ARMJIT::IsMapped(0, instrAddr))
|
||||||
|
{
|
||||||
|
NDS::ARM9Timestamp = NDS::ARM9Target;
|
||||||
|
printf("ARMv5 PC in non executable region %08X\n", R[15]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock(0, instrAddr);
|
||||||
|
Cycles += (block ? block : ARMJIT::CompileBlock(this))();
|
||||||
|
|
||||||
|
if (Halted)
|
||||||
|
{
|
||||||
|
if (Halted == 1 && NDS::ARM9Timestamp < NDS::ARM9Target)
|
||||||
|
{
|
||||||
|
NDS::ARM9Timestamp = NDS::ARM9Target;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (IRQ) TriggerIRQ();
|
||||||
|
|
||||||
|
NDS::ARM9Timestamp += Cycles;
|
||||||
|
Cycles = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Halted == 2)
|
||||||
|
Halted = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ARMv4::Execute()
|
void ARMv4::Execute()
|
||||||
{
|
{
|
||||||
if (Halted)
|
if (Halted)
|
||||||
|
@ -620,7 +666,7 @@ void ARMv4::Execute()
|
||||||
|
|
||||||
while (NDS::ARM7Timestamp < NDS::ARM7Target)
|
while (NDS::ARM7Timestamp < NDS::ARM7Target)
|
||||||
{
|
{
|
||||||
/*if (CPSR & 0x20) // THUMB
|
if (CPSR & 0x20) // THUMB
|
||||||
{
|
{
|
||||||
// prefetch
|
// prefetch
|
||||||
R[15] += 2;
|
R[15] += 2;
|
||||||
|
@ -648,13 +694,7 @@ void ARMv4::Execute()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
AddCycles_C();
|
AddCycles_C();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
/*if (!ARMJIT::IsMapped(1, R[15] - ((CPSR&0x20)?2:4)))
|
|
||||||
printf("aaarg ungempappter raum %x\n", R[15]);*/
|
|
||||||
|
|
||||||
ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock(1, R[15] - ((CPSR&0x20)?2:4));
|
|
||||||
Cycles += (block ? block : ARMJIT::CompileBlock(this))();
|
|
||||||
|
|
||||||
// TODO optimize this shit!!!
|
// TODO optimize this shit!!!
|
||||||
if (Halted)
|
if (Halted)
|
||||||
|
@ -679,3 +719,56 @@ void ARMv4::Execute()
|
||||||
if (Halted == 2)
|
if (Halted == 2)
|
||||||
Halted = 0;
|
Halted = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (!ARMJIT::IsMapped(1, instrAddr))
|
||||||
|
{
|
||||||
|
NDS::ARM7Timestamp = NDS::ARM7Target;
|
||||||
|
printf("ARMv4 PC in non executable region %08X\n", R[15]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock(1, instrAddr);
|
||||||
|
Cycles += (block ? block : ARMJIT::CompileBlock(this))();
|
||||||
|
|
||||||
|
// TODO optimize this shit!!!
|
||||||
|
if (Halted)
|
||||||
|
{
|
||||||
|
if (Halted == 1 && NDS::ARM7Timestamp < NDS::ARM7Target)
|
||||||
|
{
|
||||||
|
NDS::ARM7Timestamp = NDS::ARM7Target;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IRQ) TriggerIRQ();
|
||||||
|
|
||||||
|
NDS::ARM7Timestamp += Cycles;
|
||||||
|
Cycles = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Halted == 2)
|
||||||
|
Halted = 0;
|
||||||
|
}
|
|
@ -52,6 +52,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Execute() = 0;
|
virtual void Execute() = 0;
|
||||||
|
virtual void ExecuteJIT() = 0;
|
||||||
|
|
||||||
bool CheckCondition(u32 code)
|
bool CheckCondition(u32 code)
|
||||||
{
|
{
|
||||||
|
@ -159,6 +160,7 @@ public:
|
||||||
void DataAbort();
|
void DataAbort();
|
||||||
|
|
||||||
void Execute();
|
void Execute();
|
||||||
|
void ExecuteJIT();
|
||||||
|
|
||||||
// all code accesses are forced nonseq 32bit
|
// all code accesses are forced nonseq 32bit
|
||||||
u32 CodeRead32(u32 addr, bool branch);
|
u32 CodeRead32(u32 addr, bool branch);
|
||||||
|
@ -281,6 +283,7 @@ public:
|
||||||
void JumpTo(u32 addr, bool restorecpsr = false);
|
void JumpTo(u32 addr, bool restorecpsr = false);
|
||||||
|
|
||||||
void Execute();
|
void Execute();
|
||||||
|
void ExecuteJIT();
|
||||||
|
|
||||||
u16 CodeRead16(u32 addr)
|
u16 CodeRead16(u32 addr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
#include "ARMJIT_x64/ARMJIT_Compiler.h"
|
#include "ARMJIT_x64/ARMJIT_Compiler.h"
|
||||||
|
|
||||||
namespace ARMJIT
|
namespace ARMJIT
|
||||||
|
@ -125,18 +127,21 @@ CompiledBlock CompileBlock(ARM* cpu)
|
||||||
{
|
{
|
||||||
bool thumb = cpu->CPSR & 0x20;
|
bool thumb = cpu->CPSR & 0x20;
|
||||||
|
|
||||||
FetchedInstr instrs[12];
|
if (Config::JIT_MaxBlockSize < 1)
|
||||||
|
Config::JIT_MaxBlockSize = 1;
|
||||||
|
if (Config::JIT_MaxBlockSize > 32)
|
||||||
|
Config::JIT_MaxBlockSize = 32;
|
||||||
|
|
||||||
|
FetchedInstr instrs[Config::JIT_MaxBlockSize];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
u32 r15Initial = cpu->R[15];
|
u32 blockAddr = cpu->R[15] - (thumb ? 2 : 4);
|
||||||
u32 r15 = cpu->R[15];
|
u32 r15 = cpu->R[15];
|
||||||
u32 nextInstr[2] = {cpu->NextInstr[0], cpu->NextInstr[1]};
|
u32 nextInstr[2] = {cpu->NextInstr[0], cpu->NextInstr[1]};
|
||||||
//printf("block %x %d\n", r15, thumb);
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
r15 += thumb ? 2 : 4;
|
r15 += thumb ? 2 : 4;
|
||||||
|
|
||||||
instrs[i].Instr = nextInstr[0];
|
instrs[i].Instr = nextInstr[0];
|
||||||
//printf("%x %x\n", instrs[i].Instr, r15);
|
|
||||||
instrs[i].NextInstr[0] = nextInstr[0] = nextInstr[1];
|
instrs[i].NextInstr[0] = nextInstr[0] = nextInstr[1];
|
||||||
|
|
||||||
if (cpu->Num == 0)
|
if (cpu->Num == 0)
|
||||||
|
@ -166,16 +171,16 @@ CompiledBlock CompileBlock(ARM* cpu)
|
||||||
instrs[i].Info = ARMInstrInfo::Decode(thumb, cpu->Num, instrs[i].Instr);
|
instrs[i].Info = ARMInstrInfo::Decode(thumb, cpu->Num, instrs[i].Instr);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
} while(!instrs[i - 1].Info.Branches() && i < 10);
|
} while(!instrs[i - 1].Info.Branches() && i < Config::JIT_MaxBlockSize);
|
||||||
|
|
||||||
CompiledBlock block = compiler->CompileBlock(cpu, instrs, i);
|
CompiledBlock block = compiler->CompileBlock(cpu, instrs, i);
|
||||||
|
|
||||||
InsertBlock(cpu->Num, r15Initial - (thumb ? 2 : 4), block);
|
InsertBlock(cpu->Num, blockAddr, block);
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetBlocks()
|
void InvalidateBlockCache()
|
||||||
{
|
{
|
||||||
memset(cache.MainRAM, 0, sizeof(cache.MainRAM));
|
memset(cache.MainRAM, 0, sizeof(cache.MainRAM));
|
||||||
memset(cache.SWRAM, 0, sizeof(cache.SWRAM));
|
memset(cache.SWRAM, 0, sizeof(cache.SWRAM));
|
||||||
|
@ -185,6 +190,8 @@ void ResetBlocks()
|
||||||
memset(cache.ARM7_BIOS, 0, sizeof(cache.ARM7_BIOS));
|
memset(cache.ARM7_BIOS, 0, sizeof(cache.ARM7_BIOS));
|
||||||
memset(cache.ARM7_WRAM, 0, sizeof(cache.ARM7_WRAM));
|
memset(cache.ARM7_WRAM, 0, sizeof(cache.ARM7_WRAM));
|
||||||
memset(cache.ARM7_WVRAM, 0, sizeof(cache.ARM7_WVRAM));
|
memset(cache.ARM7_WVRAM, 0, sizeof(cache.ARM7_WVRAM));
|
||||||
|
|
||||||
|
compiler->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -111,7 +111,7 @@ void DeInit();
|
||||||
|
|
||||||
CompiledBlock CompileBlock(ARM* cpu);
|
CompiledBlock CompileBlock(ARM* cpu);
|
||||||
|
|
||||||
void ResetBlocks();
|
void InvalidateBlockCache();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -336,13 +336,15 @@ const Compiler::CompileFunc T_Comp[ARMInstrInfo::tk_Count] = {
|
||||||
};
|
};
|
||||||
#undef F
|
#undef F
|
||||||
|
|
||||||
|
void Compiler::Reset()
|
||||||
|
{
|
||||||
|
SetCodePtr((u8*)ResetStart);
|
||||||
|
}
|
||||||
|
|
||||||
CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrsCount)
|
CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrsCount)
|
||||||
{
|
{
|
||||||
if (IsAlmostFull())
|
if (IsAlmostFull())
|
||||||
{
|
InvalidateBlockCache();
|
||||||
ResetBlocks();
|
|
||||||
SetCodePtr((u8*)ResetStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
CompiledBlock res = (CompiledBlock)GetWritableCodePtr();
|
CompiledBlock res = (CompiledBlock)GetWritableCodePtr();
|
||||||
|
|
||||||
|
@ -355,7 +357,7 @@ CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrs
|
||||||
|
|
||||||
bool mergedThumbBL = false;
|
bool mergedThumbBL = false;
|
||||||
|
|
||||||
ABI_PushRegistersAndAdjustStack(BitSet32(ABI_ALL_CALLEE_SAVED & ABI_ALL_GPRS & ~RSP), 8);
|
ABI_PushRegistersAndAdjustStack(BitSet32(ABI_ALL_CALLEE_SAVED & ABI_ALL_GPRS & ~BitSet32({RSP})), 8);
|
||||||
|
|
||||||
MOV(64, R(RCPU), ImmPtr(cpu));
|
MOV(64, R(RCPU), ImmPtr(cpu));
|
||||||
|
|
||||||
|
@ -469,7 +471,7 @@ CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrs
|
||||||
|
|
||||||
MOV(32, R(RAX), Imm32(ConstantCycles));
|
MOV(32, R(RAX), Imm32(ConstantCycles));
|
||||||
|
|
||||||
ABI_PopRegistersAndAdjustStack(BitSet32(ABI_ALL_CALLEE_SAVED & ABI_ALL_GPRS & ~RSP), 8);
|
ABI_PopRegistersAndAdjustStack(BitSet32(ABI_ALL_CALLEE_SAVED & ABI_ALL_GPRS & ~BitSet32({RSP})), 8);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -22,6 +22,8 @@ class Compiler : public Gen::X64CodeBlock
|
||||||
public:
|
public:
|
||||||
Compiler();
|
Compiler();
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
CompiledBlock CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrsCount);
|
CompiledBlock CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrsCount);
|
||||||
|
|
||||||
void LoadReg(int reg, Gen::X64Reg nativeReg);
|
void LoadReg(int reg, Gen::X64Reg nativeReg);
|
||||||
|
|
|
@ -37,6 +37,9 @@ char DSiBIOS7Path[1024];
|
||||||
char DSiFirmwarePath[1024];
|
char DSiFirmwarePath[1024];
|
||||||
char DSiNANDPath[1024];
|
char DSiNANDPath[1024];
|
||||||
|
|
||||||
|
bool JIT_Enable = false;
|
||||||
|
int JIT_MaxBlockSize = 12;
|
||||||
|
|
||||||
ConfigEntry ConfigFile[] =
|
ConfigEntry ConfigFile[] =
|
||||||
{
|
{
|
||||||
{"BIOS9Path", 1, BIOS9Path, 0, "", 1023},
|
{"BIOS9Path", 1, BIOS9Path, 0, "", 1023},
|
||||||
|
@ -48,6 +51,9 @@ ConfigEntry ConfigFile[] =
|
||||||
{"DSiFirmwarePath", 1, DSiFirmwarePath, 0, "", 1023},
|
{"DSiFirmwarePath", 1, DSiFirmwarePath, 0, "", 1023},
|
||||||
{"DSiNANDPath", 1, DSiNANDPath, 0, "", 1023},
|
{"DSiNANDPath", 1, DSiNANDPath, 0, "", 1023},
|
||||||
|
|
||||||
|
{"JIT_Enable", 0, &JIT_Enable, 0, NULL, 0},
|
||||||
|
{"JIT_MaxBlockSize", 0, &JIT_MaxBlockSize, 10, NULL, 0},
|
||||||
|
|
||||||
{"", -1, NULL, 0, NULL, 0}
|
{"", -1, NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,9 @@ extern char DSiBIOS7Path[1024];
|
||||||
extern char DSiFirmwarePath[1024];
|
extern char DSiFirmwarePath[1024];
|
||||||
extern char DSiNANDPath[1024];
|
extern char DSiNANDPath[1024];
|
||||||
|
|
||||||
|
extern bool JIT_Enable;
|
||||||
|
extern int JIT_MaxBlockSize;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CONFIG_H
|
#endif // CONFIG_H
|
||||||
|
|
22
src/NDS.cpp
22
src/NDS.cpp
|
@ -566,7 +566,7 @@ void Reset()
|
||||||
KeyCnt = 0;
|
KeyCnt = 0;
|
||||||
RCnt = 0;
|
RCnt = 0;
|
||||||
|
|
||||||
ARMJIT::ResetBlocks();
|
ARMJIT::InvalidateBlockCache();
|
||||||
|
|
||||||
NDSCart::Reset();
|
NDSCart::Reset();
|
||||||
GBACart::Reset();
|
GBACart::Reset();
|
||||||
|
@ -794,6 +794,11 @@ bool DoSavestate(Savestate* file)
|
||||||
GPU::SetPowerCnt(PowerControl9);
|
GPU::SetPowerCnt(PowerControl9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!file->Saving)
|
||||||
|
{
|
||||||
|
ARMJIT::InvalidateBlockCache();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,6 +889,7 @@ void RunSystem(u64 timestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <bool EnableJIT>
|
||||||
u32 RunFrame()
|
u32 RunFrame()
|
||||||
{
|
{
|
||||||
FrameStartTimestamp = SysTimestamp;
|
FrameStartTimestamp = SysTimestamp;
|
||||||
|
@ -917,6 +923,9 @@ u32 RunFrame()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (EnableJIT)
|
||||||
|
ARM9->ExecuteJIT();
|
||||||
|
else
|
||||||
ARM9->Execute();
|
ARM9->Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,6 +949,9 @@ u32 RunFrame()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (EnableJIT)
|
||||||
|
ARM7->ExecuteJIT();
|
||||||
|
else
|
||||||
ARM7->Execute();
|
ARM7->Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -970,6 +982,14 @@ u32 RunFrame()
|
||||||
return GPU::TotalScanlines;
|
return GPU::TotalScanlines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 RunFrame()
|
||||||
|
{
|
||||||
|
if (Config::JIT_Enable)
|
||||||
|
return RunFrame<true>();
|
||||||
|
else
|
||||||
|
return RunFrame<false>();
|
||||||
|
}
|
||||||
|
|
||||||
void Reschedule(u64 target)
|
void Reschedule(u64 target)
|
||||||
{
|
{
|
||||||
if (CurCPU == 0)
|
if (CurCPU == 0)
|
||||||
|
|
|
@ -72,6 +72,7 @@ char MicWavPath[1024];
|
||||||
|
|
||||||
char LastROMFolder[1024];
|
char LastROMFolder[1024];
|
||||||
|
|
||||||
|
bool EnableJIT;
|
||||||
|
|
||||||
ConfigEntry PlatformConfigFile[] =
|
ConfigEntry PlatformConfigFile[] =
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue