use unordered map for JIT RestoreCandidates
also fix WifiRead32?
This commit is contained in:
parent
4cefff2528
commit
4299ef5f06
153
src/ARMJIT.cpp
153
src/ARMJIT.cpp
|
@ -38,6 +38,14 @@ namespace ARMJIT
|
||||||
|
|
||||||
Compiler* JITCompiler;
|
Compiler* JITCompiler;
|
||||||
|
|
||||||
|
|
||||||
|
std::unordered_map<u32, JitBlock*> JitBlocks9;
|
||||||
|
std::unordered_map<u32, JitBlock*> JitBlocks7;
|
||||||
|
|
||||||
|
std::unordered_map<u32, JitBlock*> RestoreCandidates;
|
||||||
|
|
||||||
|
TinyVector<u32> InvalidLiterals;
|
||||||
|
|
||||||
AddressRange CodeIndexITCM[ITCMPhysicalSize / 512];
|
AddressRange CodeIndexITCM[ITCMPhysicalSize / 512];
|
||||||
AddressRange CodeIndexMainRAM[NDS::MainRAMMaxSize / 512];
|
AddressRange CodeIndexMainRAM[NDS::MainRAMMaxSize / 512];
|
||||||
AddressRange CodeIndexSWRAM[NDS::SharedWRAMSize / 512];
|
AddressRange CodeIndexSWRAM[NDS::SharedWRAMSize / 512];
|
||||||
|
@ -52,9 +60,6 @@ AddressRange CodeIndexNWRAM_A[DSi::NWRAMSize / 512];
|
||||||
AddressRange CodeIndexNWRAM_B[DSi::NWRAMSize / 512];
|
AddressRange CodeIndexNWRAM_B[DSi::NWRAMSize / 512];
|
||||||
AddressRange CodeIndexNWRAM_C[DSi::NWRAMSize / 512];
|
AddressRange CodeIndexNWRAM_C[DSi::NWRAMSize / 512];
|
||||||
|
|
||||||
std::unordered_map<u32, JitBlock*> JitBlocks9;
|
|
||||||
std::unordered_map<u32, JitBlock*> JitBlocks7;
|
|
||||||
|
|
||||||
u64 FastBlockLookupITCM[ITCMPhysicalSize / 2];
|
u64 FastBlockLookupITCM[ITCMPhysicalSize / 2];
|
||||||
u64 FastBlockLookupMainRAM[NDS::MainRAMMaxSize / 2];
|
u64 FastBlockLookupMainRAM[NDS::MainRAMMaxSize / 2];
|
||||||
u64 FastBlockLookupSWRAM[NDS::SharedWRAMSize / 2];
|
u64 FastBlockLookupSWRAM[NDS::SharedWRAMSize / 2];
|
||||||
|
@ -146,8 +151,6 @@ u32 LocaliseCodeAddress(u32 num, u32 addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TinyVector<u32> InvalidLiterals;
|
|
||||||
|
|
||||||
template <typename T, int ConsoleType>
|
template <typename T, int ConsoleType>
|
||||||
T SlowRead9(u32 addr, ARMv5* cpu)
|
T SlowRead9(u32 addr, ARMv5* cpu)
|
||||||
{
|
{
|
||||||
|
@ -286,97 +289,6 @@ void SlowBlockTransfer7(u32 addr, u64* data, u32 num)
|
||||||
INSTANTIATE_SLOWMEM(0)
|
INSTANTIATE_SLOWMEM(0)
|
||||||
INSTANTIATE_SLOWMEM(1)
|
INSTANTIATE_SLOWMEM(1)
|
||||||
|
|
||||||
template <typename K, typename V, int Size, V InvalidValue>
|
|
||||||
struct UnreliableHashTable
|
|
||||||
{
|
|
||||||
struct Bucket
|
|
||||||
{
|
|
||||||
K KeyA, KeyB;
|
|
||||||
V ValA, ValB;
|
|
||||||
};
|
|
||||||
|
|
||||||
Bucket Table[Size];
|
|
||||||
|
|
||||||
void Reset()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Size; i++)
|
|
||||||
{
|
|
||||||
Table[i].ValA = Table[i].ValB = InvalidValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UnreliableHashTable()
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
V Insert(K key, V value)
|
|
||||||
{
|
|
||||||
u32 slot = XXH3_64bits(&key, sizeof(K)) & (Size - 1);
|
|
||||||
Bucket* bucket = &Table[slot];
|
|
||||||
|
|
||||||
if (bucket->ValA == value || bucket->ValB == value)
|
|
||||||
{
|
|
||||||
return InvalidValue;
|
|
||||||
}
|
|
||||||
else if (bucket->ValA == InvalidValue)
|
|
||||||
{
|
|
||||||
bucket->KeyA = key;
|
|
||||||
bucket->ValA = value;
|
|
||||||
}
|
|
||||||
else if (bucket->ValB == InvalidValue)
|
|
||||||
{
|
|
||||||
bucket->KeyB = key;
|
|
||||||
bucket->ValB = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
V prevVal = bucket->ValB;
|
|
||||||
bucket->KeyB = bucket->KeyA;
|
|
||||||
bucket->ValB = bucket->ValA;
|
|
||||||
bucket->KeyA = key;
|
|
||||||
bucket->ValA = value;
|
|
||||||
return prevVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
return InvalidValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Remove(K key)
|
|
||||||
{
|
|
||||||
u32 slot = XXH3_64bits(&key, sizeof(K)) & (Size - 1);
|
|
||||||
Bucket* bucket = &Table[slot];
|
|
||||||
|
|
||||||
if (bucket->KeyA == key && bucket->ValA != InvalidValue)
|
|
||||||
{
|
|
||||||
bucket->ValA = InvalidValue;
|
|
||||||
if (bucket->ValB != InvalidValue)
|
|
||||||
{
|
|
||||||
bucket->KeyA = bucket->KeyB;
|
|
||||||
bucket->ValA = bucket->ValB;
|
|
||||||
bucket->ValB = InvalidValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bucket->KeyB == key && bucket->ValB != InvalidValue)
|
|
||||||
bucket->ValB = InvalidValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
V LookUp(K addr)
|
|
||||||
{
|
|
||||||
u32 slot = XXH3_64bits(&addr, 4) & (Size - 1);
|
|
||||||
Bucket* bucket = &Table[slot];
|
|
||||||
|
|
||||||
if (bucket->ValA != InvalidValue && bucket->KeyA == addr)
|
|
||||||
return bucket->ValA;
|
|
||||||
if (bucket->ValB != InvalidValue && bucket->KeyB == addr)
|
|
||||||
return bucket->ValB;
|
|
||||||
|
|
||||||
return InvalidValue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
UnreliableHashTable<u32, JitBlock*, 0x800, nullptr> RestoreCandidates;
|
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
JITCompiler = new Compiler();
|
JITCompiler = new Compiler();
|
||||||
|
@ -622,6 +534,20 @@ InterpreterFunc InterpretTHUMB[ARMInstrInfo::tk_Count] =
|
||||||
};
|
};
|
||||||
#undef F
|
#undef F
|
||||||
|
|
||||||
|
void RetireJitBlock(JitBlock* block)
|
||||||
|
{
|
||||||
|
auto it = RestoreCandidates.find(block->InstrHash);
|
||||||
|
if (it != RestoreCandidates.end())
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
it->second = block;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RestoreCandidates[block->InstrHash] = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CompileBlock(ARM* cpu)
|
void CompileBlock(ARM* cpu)
|
||||||
{
|
{
|
||||||
bool thumb = cpu->CPSR & 0x20;
|
bool thumb = cpu->CPSR & 0x20;
|
||||||
|
@ -659,10 +585,7 @@ void CompileBlock(ARM* cpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
// some memory has been remapped
|
// some memory has been remapped
|
||||||
JitBlock* prevBlock = RestoreCandidates.Insert(existingBlockIt->second->InstrHash, existingBlockIt->second);
|
RetireJitBlock(existingBlockIt->second);
|
||||||
if (prevBlock)
|
|
||||||
delete prevBlock;
|
|
||||||
|
|
||||||
map.erase(existingBlockIt);
|
map.erase(existingBlockIt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,11 +829,13 @@ void CompileBlock(ARM* cpu)
|
||||||
u32 literalHash = (u32)XXH3_64bits(literalValues, numLiterals * 4);
|
u32 literalHash = (u32)XXH3_64bits(literalValues, numLiterals * 4);
|
||||||
u32 instrHash = (u32)XXH3_64bits(instrValues, i * 4);
|
u32 instrHash = (u32)XXH3_64bits(instrValues, i * 4);
|
||||||
|
|
||||||
JitBlock* prevBlock = RestoreCandidates.LookUp(instrHash);
|
auto prevBlockIt = RestoreCandidates.find(instrHash);
|
||||||
|
JitBlock* prevBlock = NULL;
|
||||||
bool mayRestore = true;
|
bool mayRestore = true;
|
||||||
if (prevBlock)
|
if (prevBlockIt != RestoreCandidates.end())
|
||||||
{
|
{
|
||||||
RestoreCandidates.Remove(instrHash);
|
prevBlock = prevBlockIt->second;
|
||||||
|
RestoreCandidates.erase(prevBlockIt);
|
||||||
|
|
||||||
mayRestore = prevBlock->StartAddr == blockAddr && prevBlock->LiteralHash == literalHash;
|
mayRestore = prevBlock->StartAddr == blockAddr && prevBlock->LiteralHash == literalHash;
|
||||||
|
|
||||||
|
@ -932,7 +857,6 @@ void CompileBlock(ARM* cpu)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mayRestore = false;
|
mayRestore = false;
|
||||||
prevBlock = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JitBlock* block;
|
JitBlock* block;
|
||||||
|
@ -1078,9 +1002,7 @@ void InvalidateByAddr(u32 localAddr)
|
||||||
|
|
||||||
if (!literalInvalidation)
|
if (!literalInvalidation)
|
||||||
{
|
{
|
||||||
JitBlock* prevBlock = RestoreCandidates.Insert(block->InstrHash, block);
|
RetireJitBlock(block);
|
||||||
if (prevBlock)
|
|
||||||
delete prevBlock;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1166,20 +1088,9 @@ void ResetBlockCache()
|
||||||
InvalidLiterals.Clear();
|
InvalidLiterals.Clear();
|
||||||
for (int i = 0; i < ARMJIT_Memory::memregions_Count; i++)
|
for (int i = 0; i < ARMJIT_Memory::memregions_Count; i++)
|
||||||
memset(FastBlockLookupRegions[i], 0xFF, CodeRegionSizes[i] * sizeof(u64) / 2);
|
memset(FastBlockLookupRegions[i], 0xFF, CodeRegionSizes[i] * sizeof(u64) / 2);
|
||||||
RestoreCandidates.Reset();
|
for (auto it = RestoreCandidates.begin(); it != RestoreCandidates.end(); it++)
|
||||||
for (int i = 0; i < sizeof(RestoreCandidates.Table)/sizeof(RestoreCandidates.Table[0]); i++)
|
delete it->second;
|
||||||
{
|
RestoreCandidates.clear();
|
||||||
if (RestoreCandidates.Table[i].ValA)
|
|
||||||
{
|
|
||||||
delete RestoreCandidates.Table[i].ValA;
|
|
||||||
RestoreCandidates.Table[i].ValA = NULL;
|
|
||||||
}
|
|
||||||
if (RestoreCandidates.Table[i].ValA)
|
|
||||||
{
|
|
||||||
delete RestoreCandidates.Table[i].ValB;
|
|
||||||
RestoreCandidates.Table[i].ValB = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto it : JitBlocks9)
|
for (auto it : JitBlocks9)
|
||||||
{
|
{
|
||||||
JitBlock* block = it.second;
|
JitBlock* block = it.second;
|
||||||
|
|
|
@ -1008,7 +1008,7 @@ void WifiWrite32(u32 addr, u32 val)
|
||||||
|
|
||||||
u32 WifiRead32(u32 addr)
|
u32 WifiRead32(u32 addr)
|
||||||
{
|
{
|
||||||
return Wifi::Read(addr) | (Wifi::Read(addr + 2) << 16);
|
return (u32)Wifi::Read(addr) | ((u32)Wifi::Read(addr + 2) << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
Loading…
Reference in New Issue