jit: decrease blockcache AddrMapping size for ARM9

This commit is contained in:
RSDuck 2019-07-21 13:36:48 +02:00
parent 03b321f540
commit 4deecc7d65
5 changed files with 77 additions and 38 deletions

View File

@ -609,14 +609,14 @@ void ARMv5::ExecuteJIT()
while (NDS::ARM9Timestamp < NDS::ARM9Target) while (NDS::ARM9Timestamp < NDS::ARM9Target)
{ {
u32 instrAddr = R[15] - ((CPSR&0x20)?2:4); u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);
if (!ARMJIT::IsMapped(0, instrAddr)) if (!ARMJIT::IsMapped<0>(instrAddr))
{ {
NDS::ARM9Timestamp = NDS::ARM9Target; NDS::ARM9Timestamp = NDS::ARM9Target;
printf("ARMv5 PC in non executable region %08X\n", R[15]); printf("ARMv5 PC in non executable region %08X\n", R[15]);
return; return;
} }
ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock(0, instrAddr); ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock<0>(instrAddr);
Cycles += (block ? block : ARMJIT::CompileBlock(this))(); Cycles += (block ? block : ARMJIT::CompileBlock(this))();
if (Halted) if (Halted)
@ -740,13 +740,13 @@ void ARMv4::ExecuteJIT()
while (NDS::ARM7Timestamp < NDS::ARM7Target) while (NDS::ARM7Timestamp < NDS::ARM7Target)
{ {
u32 instrAddr = R[15] - ((CPSR&0x20)?2:4); u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);
if (!ARMJIT::IsMapped(1, instrAddr)) if (!ARMJIT::IsMapped<1>(instrAddr))
{ {
NDS::ARM7Timestamp = NDS::ARM7Target; NDS::ARM7Timestamp = NDS::ARM7Target;
printf("ARMv4 PC in non executable region %08X\n", R[15]); printf("ARMv4 PC in non executable region %08X\n", R[15]);
return; return;
} }
ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock(1, instrAddr); ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock<1>(instrAddr);
Cycles += (block ? block : ARMJIT::CompileBlock(this))(); Cycles += (block ? block : ARMJIT::CompileBlock(this))();
// TODO optimize this shit!!! // TODO optimize this shit!!!

View File

@ -109,11 +109,14 @@ void Init()
{ {
memset(&cache, 0, sizeof(BlockCache)); memset(&cache, 0, sizeof(BlockCache));
for (int cpu = 0; cpu < 2; cpu++) for (int i = 0; i < 0x2000; i++)
for (int i = 0; i < 0x4000; i++) cache.AddrMapping9[i] = JIT_MEM[0][i >> 8] == -1 ? NULL :
cache.AddrMapping[cpu][i] = JIT_MEM[cpu][i >> 9] == -1 ? NULL : (CompiledBlock*)((u8*)&cache + JIT_MEM[0][i >> 8])
(CompiledBlock*)((u8*)&cache + JIT_MEM[cpu][i >> 9]) + (((i << 15) & JIT_MASK[0][i >> 8]) >> 1);
+ (((i << 14) & JIT_MASK[cpu][i >> 9]) >> 1); for (int i = 0; i < 0x4000; i++)
cache.AddrMapping7[i] = JIT_MEM[1][i >> 9] == -1 ? NULL :
(CompiledBlock*)((u8*)&cache + JIT_MEM[1][i >> 9])
+ (((i << 14) & JIT_MASK[1][i >> 9]) >> 1);
compiler = new Compiler(); compiler = new Compiler();
} }
@ -175,7 +178,10 @@ CompiledBlock CompileBlock(ARM* cpu)
CompiledBlock block = compiler->CompileBlock(cpu, instrs, i); CompiledBlock block = compiler->CompileBlock(cpu, instrs, i);
InsertBlock(cpu->Num, blockAddr, block); if (cpu->Num == 0)
InsertBlock<0>(blockAddr, block);
else
InsertBlock<1>(blockAddr, block);
return block; return block;
} }

View File

@ -47,9 +47,11 @@ struct FetchedInstr
a function which executes a block instructions starting from there. a function which executes a block instructions starting from there.
The most significant 4 bits of each address is ignored. This 28 bit space is The most significant 4 bits of each address is ignored. This 28 bit space is
divided into 0x4000 16 KB blocks, each of which a pointer to the relevant divided into 0x2000 32 KB for ARM9 and 0x4000 16 KB for ARM7, each of which
place inside the before mentioned arrays. Only half of the bytes need to be a pointer to the relevant place inside the afore mentioned arrays. 32 and 16 KB
addressed (ARM address are aligned to 4, Thumb addresses to a 2 byte boundary). are the sizes of the smallest contigous memory region mapped to the respective CPU.
Because ARM addresses are always aligned to 4 bytes and Thumb to a 2 byte boundary,
we only need every second half word to be adressable.
In case a memory write hits mapped memory, the function block at this In case a memory write hits mapped memory, the function block at this
address is set to null, so it's recompiled the next time it's executed. address is set to null, so it's recompiled the next time it's executed.
@ -61,7 +63,8 @@ struct FetchedInstr
struct BlockCache struct BlockCache
{ {
CompiledBlock* AddrMapping[2][0x4000] = {0}; CompiledBlock* AddrMapping9[0x2000] = {0};
CompiledBlock* AddrMapping7[0x4000] = {0};
CompiledBlock MainRAM[4*1024*1024/2]; CompiledBlock MainRAM[4*1024*1024/2];
CompiledBlock SWRAM[0x8000/2]; // Shared working RAM CompiledBlock SWRAM[0x8000/2]; // Shared working RAM
@ -75,35 +78,63 @@ struct BlockCache
extern BlockCache cache; extern BlockCache cache;
inline bool IsMapped(u32 num, u32 addr) template <u32 num>
inline bool IsMapped(u32 addr)
{ {
return cache.AddrMapping[num][(addr & 0xFFFFFFF) >> 14]; if (num == 0)
return cache.AddrMapping9[(addr & 0xFFFFFFF) >> 15];
else
return cache.AddrMapping7[(addr & 0xFFFFFFF) >> 14];
} }
inline CompiledBlock LookUpBlock(u32 num, u32 addr) template <u32 num>
inline CompiledBlock LookUpBlock(u32 addr)
{ {
return cache.AddrMapping[num][(addr & 0xFFFFFFF) >> 14][(addr & 0x3FFF) >> 1]; if (num == 0)
return cache.AddrMapping9[(addr & 0xFFFFFFF) >> 15][(addr & 0x7FFF) >> 1];
else
return cache.AddrMapping7[(addr & 0xFFFFFFF) >> 14][(addr & 0x3FFF) >> 1];
} }
inline void Invalidate16(u32 num, u32 addr) template <u32 num>
inline void Invalidate16(u32 addr)
{ {
if (IsMapped(num, addr)) if (IsMapped<num>(addr))
cache.AddrMapping[num][(addr & 0xFFFFFFF) >> 14][(addr & 0x3FFF) >> 1] = NULL;
}
inline void Invalidate32(u32 num, u32 addr)
{
if (IsMapped(num, addr))
{ {
CompiledBlock* page = cache.AddrMapping[num][(addr & 0xFFFFFFF) >> 14]; if (num == 0)
page[(addr & 0x3FFF) >> 1] = NULL; cache.AddrMapping9[(addr & 0xFFFFFFF) >> 15][(addr & 0x7FFF) >> 1] = NULL;
page[((addr + 2) & 0x3FFF) >> 1] = NULL; else
cache.AddrMapping7[(addr & 0xFFFFFFF) >> 14][(addr & 0x3FFF) >> 1] = NULL;
} }
} }
inline void InsertBlock(u32 num, u32 addr, CompiledBlock func) template <u32 num>
inline void Invalidate32(u32 addr)
{ {
cache.AddrMapping[num][(addr & 0xFFFFFFF) >> 14][(addr & 0x3FFF) >> 1] = func; if (IsMapped<num>(addr))
{
if (num == 0)
{
CompiledBlock* page = cache.AddrMapping9[(addr & 0xFFFFFFF) >> 15];
page[(addr & 0x7FFF) >> 1] = NULL;
page[((addr + 2) & 0x7FFF) >> 1] = NULL;
}
else
{
CompiledBlock* page = cache.AddrMapping7[(addr & 0xFFFFFFF) >> 14];
page[(addr & 0x3FFF) >> 1] = NULL;
page[((addr + 2) & 0x3FFF) >> 1] = NULL;
}
}
}
template <u32 num>
inline void InsertBlock(u32 addr, CompiledBlock func)
{
if (num == 0)
cache.AddrMapping9[(addr & 0xFFFFFFF) >> 15][(addr & 0x7FFF) >> 1] = func;
else
cache.AddrMapping7[(addr & 0xFFFFFFF) >> 14][(addr & 0x3FFF) >> 1] = func;
} }
void Init(); void Init();

View File

@ -363,7 +363,9 @@ CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrs
CompiledBlock res = (CompiledBlock)GetWritableCodePtr(); CompiledBlock res = (CompiledBlock)GetWritableCodePtr();
if (!IsMapped(Num, R15 - Thumb ? 2 : 4)) if (!(Num == 0
? IsMapped<0>(R15 - (Thumb ? 2 : 4))
: IsMapped<1>(R15 - (Thumb ? 2 : 4))))
{ {
printf("Trying to compile a block in unmapped memory\n"); printf("Trying to compile a block in unmapped memory\n");
} }

View File

@ -2013,7 +2013,7 @@ u32 ARM9Read32(u32 addr)
void ARM9Write8(u32 addr, u8 val) void ARM9Write8(u32 addr, u8 val)
{ {
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::Invalidate16(0, addr); ARMJIT::Invalidate16<0>(addr);
#endif #endif
switch (addr & 0xFF000000) switch (addr & 0xFF000000)
@ -2067,7 +2067,7 @@ void ARM9Write8(u32 addr, u8 val)
void ARM9Write16(u32 addr, u16 val) void ARM9Write16(u32 addr, u16 val)
{ {
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::Invalidate16(0, addr); ARMJIT::Invalidate16<0>(addr);
#endif #endif
switch (addr & 0xFF000000) switch (addr & 0xFF000000)
@ -2137,7 +2137,7 @@ void ARM9Write16(u32 addr, u16 val)
void ARM9Write32(u32 addr, u32 val) void ARM9Write32(u32 addr, u32 val)
{ {
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::Invalidate32(0, addr); ARMJIT::Invalidate32<0>(addr);
#endif #endif
switch (addr & 0xFF000000) switch (addr & 0xFF000000)
@ -2435,7 +2435,7 @@ u32 ARM7Read32(u32 addr)
void ARM7Write8(u32 addr, u8 val) void ARM7Write8(u32 addr, u8 val)
{ {
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::Invalidate16(1, addr); ARMJIT::Invalidate16<1>(addr);
#endif #endif
switch (addr & 0xFF800000) switch (addr & 0xFF800000)
@ -2498,7 +2498,7 @@ void ARM7Write8(u32 addr, u8 val)
void ARM7Write16(u32 addr, u16 val) void ARM7Write16(u32 addr, u16 val)
{ {
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::Invalidate16(1, addr); ARMJIT::Invalidate16<1>(addr);
#endif #endif
switch (addr & 0xFF800000) switch (addr & 0xFF800000)
@ -2571,7 +2571,7 @@ void ARM7Write16(u32 addr, u16 val)
void ARM7Write32(u32 addr, u32 val) void ARM7Write32(u32 addr, u32 val)
{ {
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
ARMJIT::Invalidate32(1, addr); ARMJIT::Invalidate32<1>(addr);
#endif #endif
switch (addr & 0xFF800000) switch (addr & 0xFF800000)