Invalidated the JIT cache when the dcbst instruction is used.

This commit is contained in:
skidau 2012-05-13 21:07:03 +10:00
parent 48bf5c739d
commit b27f471488
5 changed files with 15 additions and 35 deletions

View File

@ -363,7 +363,7 @@ void Interpreter::dcbf(UGeckoInstruction _inst)
{ {
NPC = PC + 12; NPC = PC + 12;
}*/ }*/
// Invalidate the icache on dcbf // Invalidate the jit block cache on dcbf
if (jit) if (jit)
{ {
u32 address = Helper_Get_EA_X(_inst); u32 address = Helper_Get_EA_X(_inst);
@ -374,7 +374,7 @@ void Interpreter::dcbf(UGeckoInstruction _inst)
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 to the data cache // 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
// However, we invalidate the icache on dcbi // However, we invalidate the jit block cache on dcbi
if (jit) if (jit)
{ {
u32 address = Helper_Get_EA_X(_inst); u32 address = Helper_Get_EA_X(_inst);
@ -385,6 +385,12 @@ void Interpreter::dcbi(UGeckoInstruction _inst)
void Interpreter::dcbst(UGeckoInstruction _inst) void Interpreter::dcbst(UGeckoInstruction _inst)
{ {
// Cache line flush. Since we don't emulate the data cache, we don't need to do anything. // Cache line flush. Since we don't emulate the data cache, we don't need to do anything.
// Invalidate the jit block cache on dcbst in case new code has been loaded via the data cache
if (jit)
{
u32 address = Helper_Get_EA_X(_inst);
jit->GetBlockCache()->InvalidateICache(address & ~0x1f, 32);
}
} }
void Interpreter::dcbt(UGeckoInstruction _inst) void Interpreter::dcbt(UGeckoInstruction _inst)

View File

@ -210,7 +210,7 @@ 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::DoNothing}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, {54, &Jit64::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}},
{86, &Jit64::Default}, //"dcbf", OPTYPE_DCACHE, 0, 4}}, {86, &Jit64::Default}, //"dcbf", OPTYPE_DCACHE, 0, 4}},
{246, &Jit64::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}}, {246, &Jit64::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}},
{278, &Jit64::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}}, {278, &Jit64::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}},

View File

@ -212,7 +212,7 @@ 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::DoNothing}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, {54, &JitIL::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}},
{86, &JitIL::Default}, //"dcbf", OPTYPE_DCACHE, 0, 4}}, {86, &JitIL::Default}, //"dcbf", OPTYPE_DCACHE, 0, 4}},
{246, &JitIL::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}}, {246, &JitIL::DoNothing}, //"dcbtst", OPTYPE_DCACHE, 0, 1}},
{278, &JitIL::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}}, {278, &JitIL::DoNothing}, //"dcbt", OPTYPE_DCACHE, 0, 1}},

View File

@ -208,23 +208,9 @@ bool JitBlock::ContainsAddress(u32 em_address)
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);
Memory::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num); Memory::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num);
u32 pAddr = 0;
// Convert the logical address to a physical address for the block map // Convert the logical address to a physical address for the block map
switch ((b.originalAddress >> 24) & 0xFC) u32 pAddr = b.originalAddress & 0x1FFFFFFF;
{
case 0x00:
case 0x80:
case 0xC0:
pAddr = b.originalAddress & 0x0FFFFFFF;
case 0x10:
case 0x90:
case 0xD0:
pAddr = b.originalAddress & 0x1FFFFFFF;
default:
// Translate address?
pAddr = b.originalAddress & 0x0FFFFFFF;
}
block_map[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num; block_map[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num;
if (block_link) if (block_link)
@ -430,21 +416,7 @@ bool JitBlock::ContainsAddress(u32 em_address)
void JitBlockCache::InvalidateICache(u32 address, const u32 length) void JitBlockCache::InvalidateICache(u32 address, const u32 length)
{ {
// Convert the logical address to a physical address for the block map // Convert the logical address to a physical address for the block map
u32 pAddr = 0; u32 pAddr = address & 0x1FFFFFFF;
switch ((address >> 24) & 0xFC)
{
case 0x00:
case 0x80:
case 0xC0:
pAddr = address & 0x0FFFFFFF;
case 0x10:
case 0x90:
case 0xD0:
pAddr = address & 0x1FFFFFFF;
default:
// Translate address?
pAddr = address & 0x0FFFFFFF;
}
// destroy JIT blocks // destroy JIT blocks
// !! this works correctly under assumption that any two overlapping blocks end at the same address // !! this works correctly under assumption that any two overlapping blocks end at the same address

View File

@ -559,7 +559,9 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa,
} }
else else
{ {
// Memory exception occurred // Critical memory exception occurred (game over)
address = LR;
broken_block = true;
break; break;
} }
} }