Merge branch 'JitCache' of https://skidau@code.google.com/p/dolphin-emu/
This commit is contained in:
commit
1387da7900
|
@ -265,6 +265,7 @@ inline void WriteToHardware(u32 em_address, const T data, u32 effective_address,
|
||||||
((em_address & 0xF0000000) == 0xC0000000) ||
|
((em_address & 0xF0000000) == 0xC0000000) ||
|
||||||
((em_address & 0xF0000000) == 0x00000000))
|
((em_address & 0xF0000000) == 0x00000000))
|
||||||
{
|
{
|
||||||
|
PowerPC::ppcState.iCache.InvalidateBlock(em_address);
|
||||||
*(T*)&m_pRAM[em_address & RAM_MASK] = bswap(data);
|
*(T*)&m_pRAM[em_address & RAM_MASK] = bswap(data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -272,6 +273,7 @@ inline void WriteToHardware(u32 em_address, const T data, u32 effective_address,
|
||||||
((em_address & 0xF0000000) == 0xD0000000) ||
|
((em_address & 0xF0000000) == 0xD0000000) ||
|
||||||
((em_address & 0xF0000000) == 0x10000000))
|
((em_address & 0xF0000000) == 0x10000000))
|
||||||
{
|
{
|
||||||
|
PowerPC::ppcState.iCache.InvalidateBlock(em_address);
|
||||||
*(T*)&m_pEXRAM[em_address & EXRAM_MASK] = bswap(data);
|
*(T*)&m_pEXRAM[em_address & EXRAM_MASK] = bswap(data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -284,6 +286,7 @@ inline void WriteToHardware(u32 em_address, const T data, u32 effective_address,
|
||||||
(bFakeVMEM && ((em_address &0xF0000000) == 0x40000000)))
|
(bFakeVMEM && ((em_address &0xF0000000) == 0x40000000)))
|
||||||
{
|
{
|
||||||
// fake VMEM
|
// fake VMEM
|
||||||
|
PowerPC::ppcState.iCache.InvalidateBlock(em_address);
|
||||||
*(T*)&m_pFakeVMEM[em_address & FAKEVMEM_MASK] = bswap(data);
|
*(T*)&m_pFakeVMEM[em_address & FAKEVMEM_MASK] = bswap(data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -363,12 +363,23 @@ void Interpreter::dcbf(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
NPC = PC + 12;
|
NPC = PC + 12;
|
||||||
}*/
|
}*/
|
||||||
|
// Invalidate the icache on dcbf
|
||||||
|
if (jit)
|
||||||
|
{
|
||||||
|
u32 address = Helper_Get_EA_X(_inst);
|
||||||
|
jit->GetBlockCache()->InvalidateICache(address & ~0x1f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::dcbi(UGeckoInstruction _inst)
|
void Interpreter::dcbi(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// Removes a block from data cache. Since we don't emulate the data cache, we don't need to do anything.
|
// Removes a block from data cache. Since we don't emulate the data cache, we don't need to do anything to the data cache
|
||||||
// Seen used during initialization.
|
// However, we invalidate the icache on dcbi
|
||||||
|
if (jit)
|
||||||
|
{
|
||||||
|
u32 address = Helper_Get_EA_X(_inst);
|
||||||
|
jit->GetBlockCache()->InvalidateICache(address & ~0x1f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::dcbst(UGeckoInstruction _inst)
|
void Interpreter::dcbst(UGeckoInstruction _inst)
|
||||||
|
|
|
@ -393,6 +393,7 @@ void STACKALIGN Jit64::Jit(u32 em_address)
|
||||||
{
|
{
|
||||||
ClearCache();
|
ClearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
int block_num = blocks.AllocateBlock(em_address);
|
int block_num = blocks.AllocateBlock(em_address);
|
||||||
JitBlock *b = blocks.GetBlock(block_num);
|
JitBlock *b = blocks.GetBlock(block_num);
|
||||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, &code_buffer, b));
|
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, &code_buffer, b));
|
||||||
|
@ -612,14 +613,14 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
if (js.compilerPC & JIT_ICACHE_VMEM_BIT)
|
if (js.compilerPC & JIT_ICACHE_VMEM_BIT)
|
||||||
MOV(32, M((jit->GetBlockCache()->GetICacheVMEM() + (js.compilerPC & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
|
MOV(32, M((jit->GetBlockCache()->GetICacheVMEM() + (js.compilerPC & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
|
||||||
else if (js.blockStart & JIT_ICACHE_EXRAM_BIT)
|
else if (js.compilerPC & JIT_ICACHE_EXRAM_BIT)
|
||||||
MOV(32, M((jit->GetBlockCache()->GetICacheEx() + (js.compilerPC & JIT_ICACHEEX_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
|
MOV(32, M((jit->GetBlockCache()->GetICacheEx() + (js.compilerPC & JIT_ICACHEEX_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
|
||||||
else
|
else
|
||||||
MOV(32, M((jit->GetBlockCache()->GetICache() + (js.compilerPC & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
|
MOV(32, M((jit->GetBlockCache()->GetICache() + (js.compilerPC & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
|
||||||
#else
|
#else
|
||||||
if (js.compilerPC & JIT_ICACHE_VMEM_BIT)
|
if (js.compilerPC & JIT_ICACHE_VMEM_BIT)
|
||||||
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICacheVMEM() + (js.compilerPC & JIT_ICACHE_MASK)));
|
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICacheVMEM() + (js.compilerPC & JIT_ICACHE_MASK)));
|
||||||
else if (js.blockStart & JIT_ICACHE_EXRAM_BIT)
|
else if (js.compilerPC & JIT_ICACHE_EXRAM_BIT)
|
||||||
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICacheEx() + (js.compilerPC & JIT_ICACHEEX_MASK)));
|
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICacheEx() + (js.compilerPC & JIT_ICACHEEX_MASK)));
|
||||||
else
|
else
|
||||||
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICache() + (js.compilerPC & JIT_ICACHE_MASK)));
|
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICache() + (js.compilerPC & JIT_ICACHE_MASK)));
|
||||||
|
|
|
@ -210,12 +210,12 @@ static GekkoOPTemplate table31[] =
|
||||||
{824, &Jit64::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
{824, &Jit64::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
||||||
{24, &Jit64::slwx}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
{24, &Jit64::slwx}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
||||||
|
|
||||||
{54, &Jit64::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}},
|
{54, &Jit64::DoNothing}, //"dcbst", OPTYPE_DCACHE, 0, 4}},
|
||||||
{86, &Jit64::DoNothing}, //"dcbf", OPTYPE_DCACHE, 0, 4}},
|
{86, &Jit64::Default}, //"dcbf", OPTYPE_DCACHE, 0, 4}},
|
||||||
{246, &Jit64::Default}, //"dcbtst", OPTYPE_DCACHE, 0, 1}},
|
{246, &Jit64::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}},
|
||||||
{278, &Jit64::Default}, //"dcbt", OPTYPE_DCACHE, 0, 1}},
|
{278, &Jit64::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}},
|
||||||
{470, &Jit64::Default}, //"dcbi", OPTYPE_DCACHE, 0, 4}},
|
{470, &Jit64::Default}, //"dcbi", OPTYPE_DCACHE, 0, 4}},
|
||||||
{758, &Jit64::Default}, //"dcba", OPTYPE_DCACHE, 0, 4}},
|
{758, &Jit64::DoNothing}, //"dcba", OPTYPE_DCACHE, 0, 4}},
|
||||||
{1014, &Jit64::dcbz}, //"dcbz", OPTYPE_DCACHE, 0, 4}},
|
{1014, &Jit64::dcbz}, //"dcbz", OPTYPE_DCACHE, 0, 4}},
|
||||||
|
|
||||||
//load word
|
//load word
|
||||||
|
|
|
@ -494,7 +494,7 @@ void JitIL::Trace()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NOTICE_LOG(DYNA_REC, "JITIL PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s",
|
DEBUG_LOG(DYNA_REC, "JITIL PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s",
|
||||||
PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3],
|
PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3],
|
||||||
PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr,
|
PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr,
|
||||||
PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs);
|
PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs);
|
||||||
|
|
|
@ -212,12 +212,12 @@ static GekkoOPTemplate table31[] =
|
||||||
{824, &JitIL::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
{824, &JitIL::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
||||||
{24, &JitIL::slwx}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
{24, &JitIL::slwx}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
||||||
|
|
||||||
{54, &JitIL::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}},
|
{54, &JitIL::DoNothing}, //"dcbst", OPTYPE_DCACHE, 0, 4}},
|
||||||
{86, &JitIL::DoNothing}, //"dcbf", OPTYPE_DCACHE, 0, 4}},
|
{86, &JitIL::Default}, //"dcbf", OPTYPE_DCACHE, 0, 4}},
|
||||||
{246, &JitIL::Default}, //"dcbtst", OPTYPE_DCACHE, 0, 1}},
|
{246, &JitIL::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}},
|
||||||
{278, &JitIL::Default}, //"dcbt", OPTYPE_DCACHE, 0, 1}},
|
{278, &JitIL::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}},
|
||||||
{470, &JitIL::Default}, //"dcbi", OPTYPE_DCACHE, 0, 4}},
|
{470, &JitIL::Default}, //"dcbi", OPTYPE_DCACHE, 0, 4}},
|
||||||
{758, &JitIL::Default}, //"dcba", OPTYPE_DCACHE, 0, 4}},
|
{758, &JitIL::DoNothing}, //"dcba", OPTYPE_DCACHE, 0, 4}},
|
||||||
{1014, &JitIL::dcbz}, //"dcbz", OPTYPE_DCACHE, 0, 4}},
|
{1014, &JitIL::dcbz}, //"dcbz", OPTYPE_DCACHE, 0, 4}},
|
||||||
//load word
|
//load word
|
||||||
{23, &JitIL::lXzx}, //"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
{23, &JitIL::lXzx}, //"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
|
||||||
|
|
|
@ -126,16 +126,16 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||||
// This clears the JIT cache. It's called from JitCache.cpp when the JIT cache
|
// This clears the JIT cache. It's called from JitCache.cpp when the JIT cache
|
||||||
// is full and when saving and loading states.
|
// is full and when saving and loading states.
|
||||||
void JitBlockCache::Clear()
|
void JitBlockCache::Clear()
|
||||||
{
|
{
|
||||||
Core::DisplayMessage("Clearing code cache.", 3000);
|
Core::DisplayMessage("Clearing code cache.", 3000);
|
||||||
for (int i = 0; i < num_blocks; i++)
|
for (int i = 0; i < num_blocks; i++)
|
||||||
{
|
{
|
||||||
DestroyBlock(i, false);
|
DestroyBlock(i, false);
|
||||||
}
|
}
|
||||||
links_to.clear();
|
links_to.clear();
|
||||||
block_map.clear();
|
|
||||||
num_blocks = 0;
|
num_blocks = 0;
|
||||||
memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS);
|
memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS);
|
||||||
|
ClearSafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitBlockCache::ClearSafe()
|
void JitBlockCache::ClearSafe()
|
||||||
|
@ -207,8 +207,9 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||||
blockCodePointers[block_num] = code_ptr;
|
blockCodePointers[block_num] = code_ptr;
|
||||||
JitBlock &b = blocks[block_num];
|
JitBlock &b = blocks[block_num];
|
||||||
b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress);
|
b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress);
|
||||||
|
if ((b.originalAddress + b.originalSize) > code_high)
|
||||||
|
code_high = b.originalAddress + b.originalSize;
|
||||||
Memory::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num);
|
Memory::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num);
|
||||||
block_map[std::make_pair(b.originalAddress + 4 * b.originalSize - 1, b.originalAddress)] = block_num;
|
|
||||||
if (block_link)
|
if (block_link)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
|
@ -355,79 +356,44 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||||
|
|
||||||
void JitBlockCache::DestroyBlock(int block_num, bool invalidate)
|
void JitBlockCache::DestroyBlock(int block_num, bool invalidate)
|
||||||
{
|
{
|
||||||
if (block_num < 0 || block_num >= num_blocks)
|
|
||||||
{
|
|
||||||
PanicAlert("DestroyBlock: Invalid block number %d", block_num);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
JitBlock &b = blocks[block_num];
|
JitBlock &b = blocks[block_num];
|
||||||
if (b.invalid)
|
if (b.invalid)
|
||||||
{
|
{
|
||||||
if (invalidate)
|
|
||||||
PanicAlert("Invalidating invalid block %d", block_num);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
b.invalid = true;
|
b.invalid = true;
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
Memory::Write_Opcode_JIT(b.originalAddress, b.originalFirstOpcode?b.originalFirstOpcode:JIT_ICACHE_INVALID_WORD);
|
Memory::Write_Opcode_JIT(b.originalAddress, JIT_ICACHE_INVALID_WORD);
|
||||||
#else
|
#else
|
||||||
if (Memory::ReadFast32(b.originalAddress) == block_num)
|
if (Memory::ReadFast32(b.originalAddress) == block_num)
|
||||||
Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress);
|
Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We don't unlink blocks, we just send anyone who tries to run them back to the dispatcher.
|
|
||||||
// Not entirely ideal, but .. pretty good.
|
|
||||||
// Spurious entrances from previously linked blocks can only come through checkedEntry
|
|
||||||
XEmitter emit((u8 *)b.checkedEntry);
|
|
||||||
emit.MOV(32, M(&PC), Imm32(b.originalAddress));
|
|
||||||
emit.JMP(jit->GetAsmRoutines()->dispatcher, true);
|
|
||||||
// this is not needed really
|
|
||||||
/*
|
|
||||||
emit.SetCodePtr((u8 *)blockCodePointers[blocknum]);
|
|
||||||
emit.MOV(32, M(&PC), Imm32(b.originalAddress));
|
|
||||||
emit.JMP(asm_routines.dispatcher, true);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JitBlockCache::InvalidateICache(u32 address)
|
void JitBlockCache::InvalidateICache(u32 address)
|
||||||
{
|
{
|
||||||
address &= ~0x1f;
|
address &= ~0x1f;
|
||||||
// destroy JIT blocks
|
|
||||||
// !! this works correctly under assumption that any two overlapping blocks end at the same address
|
|
||||||
std::map<pair<u32,u32>, u32>::iterator it1 = block_map.lower_bound(std::make_pair(address, 0)), it2 = it1, it;
|
|
||||||
while (it2 != block_map.end() && it2->first.second < address + 0x20)
|
|
||||||
{
|
|
||||||
DestroyBlock(it2->second, true);
|
|
||||||
it2++;
|
|
||||||
}
|
|
||||||
if (it1 != it2)
|
|
||||||
{
|
|
||||||
block_map.erase(it1, it2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
// invalidate iCache.
|
|
||||||
// icbi can be called with any address, so we should check
|
|
||||||
if ((address & ~JIT_ICACHE_MASK) != 0x80000000 && (address & ~JIT_ICACHE_MASK) != 0x00000000 &&
|
|
||||||
(address & ~JIT_ICACHE_MASK) != 0x7e000000 && // TLB area
|
|
||||||
(address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (address & ~JIT_ICACHEEX_MASK) != 0x10000000)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (address & JIT_ICACHE_VMEM_BIT)
|
if (address & JIT_ICACHE_VMEM_BIT)
|
||||||
{
|
{
|
||||||
u32 cacheaddr = address & JIT_ICACHE_MASK;
|
u32 cacheaddr = address & JIT_ICACHE_MASK;
|
||||||
|
if (cacheaddr > (code_high & JIT_ICACHE_MASK))
|
||||||
|
return;
|
||||||
memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, 32);
|
memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, 32);
|
||||||
}
|
}
|
||||||
else if (address & JIT_ICACHE_EXRAM_BIT)
|
else if (address & JIT_ICACHE_EXRAM_BIT)
|
||||||
{
|
{
|
||||||
u32 cacheaddr = address & JIT_ICACHEEX_MASK;
|
u32 cacheaddr = address & JIT_ICACHEEX_MASK;
|
||||||
|
if (cacheaddr > (code_high & JIT_ICACHEEX_MASK))
|
||||||
|
return;
|
||||||
memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, 32);
|
memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, 32);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u32 cacheaddr = address & JIT_ICACHE_MASK;
|
u32 cacheaddr = address & JIT_ICACHE_MASK;
|
||||||
|
if (cacheaddr > (code_high & JIT_ICACHE_MASK))
|
||||||
|
return;
|
||||||
memset(iCache + cacheaddr, JIT_ICACHE_INVALID_BYTE, 32);
|
memset(iCache + cacheaddr, JIT_ICACHE_INVALID_BYTE, 32);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,7 +76,6 @@ class JitBlockCache
|
||||||
JitBlock *blocks;
|
JitBlock *blocks;
|
||||||
int num_blocks;
|
int num_blocks;
|
||||||
std::multimap<u32, int> links_to;
|
std::multimap<u32, int> links_to;
|
||||||
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
|
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
u8 *iCache;
|
u8 *iCache;
|
||||||
u8 *iCacheEx;
|
u8 *iCacheEx;
|
||||||
|
@ -105,6 +104,7 @@ public:
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
bool IsFull() const;
|
bool IsFull() const;
|
||||||
|
u32 code_high;
|
||||||
|
|
||||||
// Code Cache
|
// Code Cache
|
||||||
JitBlock *GetBlock(int block_num);
|
JitBlock *GetBlock(int block_num);
|
||||||
|
|
|
@ -82,8 +82,6 @@ namespace PowerPC
|
||||||
|
|
||||||
void InstructionCache::Invalidate(u32 addr)
|
void InstructionCache::Invalidate(u32 addr)
|
||||||
{
|
{
|
||||||
if (jit)
|
|
||||||
jit->GetBlockCache()->InvalidateICache(addr);
|
|
||||||
if (!HID0.ICE)
|
if (!HID0.ICE)
|
||||||
return;
|
return;
|
||||||
// invalidates the whole set
|
// invalidates the whole set
|
||||||
|
@ -101,6 +99,14 @@ namespace PowerPC
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
valid[set] = 0;
|
valid[set] = 0;
|
||||||
|
if (jit)
|
||||||
|
jit->GetBlockCache()->InvalidateICache(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstructionCache::InvalidateBlock(u32 addr)
|
||||||
|
{
|
||||||
|
if (jit)
|
||||||
|
jit->GetBlockCache()->InvalidateICache(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 InstructionCache::ReadInstruction(u32 addr)
|
u32 InstructionCache::ReadInstruction(u32 addr)
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace PowerPC
|
||||||
void Reset();
|
void Reset();
|
||||||
u32 ReadInstruction(u32 addr);
|
u32 ReadInstruction(u32 addr);
|
||||||
void Invalidate(u32 addr);
|
void Invalidate(u32 addr);
|
||||||
|
void InvalidateBlock(u32 addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue