aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ARM.cpp8
-rw-r--r--src/ARMJIT.cpp18
-rw-r--r--src/ARMJIT.h67
-rw-r--r--src/ARMJIT_x64/ARMJIT_Compiler.cpp4
-rw-r--r--src/NDS.cpp12
5 files changed, 74 insertions, 35 deletions
diff --git a/src/ARM.cpp b/src/ARM.cpp
index eb58d02..b68b5eb 100644
--- a/src/ARM.cpp
+++ b/src/ARM.cpp
@@ -566,14 +566,14 @@ void ARMv5::ExecuteJIT()
while (NDS::ARM9Timestamp < NDS::ARM9Target)
{
u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);
- if (!ARMJIT::IsMapped(0, instrAddr))
+ 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);
+ ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock<0>(instrAddr);
Cycles += (block ? block : ARMJIT::CompileBlock(this))();
if (Halted)
@@ -697,13 +697,13 @@ void ARMv4::ExecuteJIT()
while (NDS::ARM7Timestamp < NDS::ARM7Target)
{
u32 instrAddr = R[15] - ((CPSR&0x20)?2:4);
- if (!ARMJIT::IsMapped(1, instrAddr))
+ 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);
+ ARMJIT::CompiledBlock block = ARMJIT::LookUpBlock<1>(instrAddr);
Cycles += (block ? block : ARMJIT::CompileBlock(this))();
// TODO optimize this shit!!!
diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp
index e8e6be0..aad14c0 100644
--- a/src/ARMJIT.cpp
+++ b/src/ARMJIT.cpp
@@ -109,11 +109,14 @@ void Init()
{
memset(&cache, 0, sizeof(BlockCache));
- for (int cpu = 0; cpu < 2; cpu++)
- for (int i = 0; i < 0x4000; i++)
- cache.AddrMapping[cpu][i] = JIT_MEM[cpu][i >> 9] == -1 ? NULL :
- (CompiledBlock*)((u8*)&cache + JIT_MEM[cpu][i >> 9])
- + (((i << 14) & JIT_MASK[cpu][i >> 9]) >> 1);
+ for (int i = 0; i < 0x2000; i++)
+ cache.AddrMapping9[i] = JIT_MEM[0][i >> 8] == -1 ? NULL :
+ (CompiledBlock*)((u8*)&cache + JIT_MEM[0][i >> 8])
+ + (((i << 15) & JIT_MASK[0][i >> 8]) >> 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();
}
@@ -175,7 +178,10 @@ CompiledBlock CompileBlock(ARM* cpu)
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;
}
diff --git a/src/ARMJIT.h b/src/ARMJIT.h
index 004256c..0fc1c38 100644
--- a/src/ARMJIT.h
+++ b/src/ARMJIT.h
@@ -47,9 +47,11 @@ struct FetchedInstr
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
- divided into 0x4000 16 KB blocks, each of which a pointer to the relevant
- place inside the before mentioned arrays. Only half of the bytes need to be
- addressed (ARM address are aligned to 4, Thumb addresses to a 2 byte boundary).
+ divided into 0x2000 32 KB for ARM9 and 0x4000 16 KB for ARM7, each of which
+ a pointer to the relevant place inside the afore mentioned arrays. 32 and 16 KB
+ 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
address is set to null, so it's recompiled the next time it's executed.
@@ -61,7 +63,8 @@ struct FetchedInstr
struct BlockCache
{
- CompiledBlock* AddrMapping[2][0x4000] = {0};
+ CompiledBlock* AddrMapping9[0x2000] = {0};
+ CompiledBlock* AddrMapping7[0x4000] = {0};
CompiledBlock MainRAM[4*1024*1024/2];
CompiledBlock SWRAM[0x8000/2]; // Shared working RAM
@@ -75,35 +78,63 @@ struct BlockCache
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))
- cache.AddrMapping[num][(addr & 0xFFFFFFF) >> 14][(addr & 0x3FFF) >> 1] = NULL;
+ if (IsMapped<num>(addr))
+ {
+ if (num == 0)
+ cache.AddrMapping9[(addr & 0xFFFFFFF) >> 15][(addr & 0x7FFF) >> 1] = NULL;
+ else
+ cache.AddrMapping7[(addr & 0xFFFFFFF) >> 14][(addr & 0x3FFF) >> 1] = NULL;
+ }
}
-inline void Invalidate32(u32 num, u32 addr)
+template <u32 num>
+inline void Invalidate32(u32 addr)
{
- if (IsMapped(num, addr))
+ if (IsMapped<num>(addr))
{
- CompiledBlock* page = cache.AddrMapping[num][(addr & 0xFFFFFFF) >> 14];
- page[(addr & 0x3FFF) >> 1] = NULL;
- page[((addr + 2) & 0x3FFF) >> 1] = NULL;
+ 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;
+ }
}
}
-inline void InsertBlock(u32 num, u32 addr, CompiledBlock func)
+template <u32 num>
+inline void InsertBlock(u32 addr, CompiledBlock func)
{
- cache.AddrMapping[num][(addr & 0xFFFFFFF) >> 14][(addr & 0x3FFF) >> 1] = 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();
diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.cpp b/src/ARMJIT_x64/ARMJIT_Compiler.cpp
index 1e871fd..cb11f73 100644
--- a/src/ARMJIT_x64/ARMJIT_Compiler.cpp
+++ b/src/ARMJIT_x64/ARMJIT_Compiler.cpp
@@ -363,7 +363,9 @@ CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrs
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");
}
diff --git a/src/NDS.cpp b/src/NDS.cpp
index 62a52aa..cab78b5 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -1864,7 +1864,7 @@ u32 ARM9Read32(u32 addr)
void ARM9Write8(u32 addr, u8 val)
{
#ifdef JIT_ENABLED
- ARMJIT::Invalidate16(0, addr);
+ ARMJIT::Invalidate16<0>(addr);
#endif
switch (addr & 0xFF000000)
@@ -1918,7 +1918,7 @@ void ARM9Write8(u32 addr, u8 val)
void ARM9Write16(u32 addr, u16 val)
{
#ifdef JIT_ENABLED
- ARMJIT::Invalidate16(0, addr);
+ ARMJIT::Invalidate16<0>(addr);
#endif
switch (addr & 0xFF000000)
@@ -1988,7 +1988,7 @@ void ARM9Write16(u32 addr, u16 val)
void ARM9Write32(u32 addr, u32 val)
{
#ifdef JIT_ENABLED
- ARMJIT::Invalidate32(0, addr);
+ ARMJIT::Invalidate32<0>(addr);
#endif
switch (addr & 0xFF000000)
@@ -2285,7 +2285,7 @@ u32 ARM7Read32(u32 addr)
void ARM7Write8(u32 addr, u8 val)
{
#ifdef JIT_ENABLED
- ARMJIT::Invalidate16(1, addr);
+ ARMJIT::Invalidate16<1>(addr);
#endif
switch (addr & 0xFF800000)
@@ -2348,7 +2348,7 @@ void ARM7Write8(u32 addr, u8 val)
void ARM7Write16(u32 addr, u16 val)
{
#ifdef JIT_ENABLED
- ARMJIT::Invalidate16(1, addr);
+ ARMJIT::Invalidate16<1>(addr);
#endif
switch (addr & 0xFF800000)
@@ -2421,7 +2421,7 @@ void ARM7Write16(u32 addr, u16 val)
void ARM7Write32(u32 addr, u32 val)
{
#ifdef JIT_ENABLED
- ARMJIT::Invalidate32(1, addr);
+ ARMJIT::Invalidate32<1>(addr);
#endif
switch (addr & 0xFF800000)