aboutsummaryrefslogtreecommitdiff
path: root/src/ARMJIT.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ARMJIT.h')
-rw-r--r--src/ARMJIT.h67
1 files changed, 49 insertions, 18 deletions
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();