One shudders to imagine what inhuman thoughts lie behind that code.

(Read_Opcode_JIT and Write_Opcode_JIT read/write from unrelated memory
areas.*  Rename the latter and refactor.)

*except at the one specific exception handler where it doesn't.  I
have no idea what this is supposed to do, but it probably doesn't do
it correctly.  For now, remove the exception.
This commit is contained in:
comex 2013-10-09 16:44:20 -04:00
parent 2e32f11f03
commit 8962b9606b
9 changed files with 30 additions and 121 deletions

View file

@ -704,19 +704,9 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
// Remove the invalid instruction from the icache, forcing a recompile
#ifdef _M_IX86
if (js.compilerPC & JIT_ICACHE_VMEM_BIT)
MOV(32, M((jit->GetBlockCache()->iCacheVMEM + (js.compilerPC & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
else if (js.compilerPC & JIT_ICACHE_EXRAM_BIT)
MOV(32, M((jit->GetBlockCache()->iCacheEx + (js.compilerPC & JIT_ICACHEEX_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
else
MOV(32, M((jit->GetBlockCache()->iCache + (js.compilerPC & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
MOV(32, M(jit->GetBlockCache()->GetICachePtr(js.compilerPC)), Imm32(JIT_ICACHE_INVALID_WORD));
#else
if (js.compilerPC & JIT_ICACHE_VMEM_BIT)
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCacheVMEM + (js.compilerPC & JIT_ICACHE_MASK)));
else if (js.compilerPC & JIT_ICACHE_EXRAM_BIT)
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCacheEx + (js.compilerPC & JIT_ICACHEEX_MASK)));
else
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCache + (js.compilerPC & JIT_ICACHE_MASK)));
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICachePtr(js.compilerPC)));
MOV(32,MatR(RAX),Imm32(JIT_ICACHE_INVALID_WORD));
#endif

View file

@ -142,9 +142,8 @@ void Jit64AsmRoutineManager::Generate()
if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack))
SetJumpTarget(exit_vmem);
TEST(32, R(EAX), Imm32(0xFC));
FixupBranch notfound = J_CC(CC_NZ);
BSWAP(32, EAX);
TEST(32, R(EAX), R(EAX));
FixupBranch notfound = J_CC(CC_L);
//IDEA - we have 26 bits, why not just use offsets from base of code?
if (enableDebug)
{

View file

@ -1764,20 +1764,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) {
// Remove the invalid instruction from the icache, forcing a recompile
#ifdef _M_IX86
if (InstLoc & JIT_ICACHE_VMEM_BIT)
Jit->MOV(32, M((jit->GetBlockCache()->iCacheVMEM + (InstLoc & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
else if (InstLoc & JIT_ICACHE_EXRAM_BIT)
Jit->MOV(32, M((jit->GetBlockCache()->iCacheEx + (InstLoc & JIT_ICACHEEX_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
else
Jit->MOV(32, M((jit->GetBlockCache()->iCache + (InstLoc & JIT_ICACHE_MASK))), Imm32(JIT_ICACHE_INVALID_WORD));
Jit->MOV(32, M(jit->GetBlockCache()->GetICachePtr(InstLoc)), Imm32(JIT_ICACHE_INVALID_WORD));
#else
if (InstLoc & JIT_ICACHE_VMEM_BIT)
Jit->MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCacheVMEM + (InstLoc & JIT_ICACHE_MASK)));
else if (InstLoc & JIT_ICACHE_EXRAM_BIT)
Jit->MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCacheEx + (InstLoc & JIT_ICACHEEX_MASK)));
else
Jit->MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->iCache + (InstLoc & JIT_ICACHE_MASK)));
Jit->MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICachePtr(InstLoc)));
Jit->MOV(32, MatR(RAX), Imm32(JIT_ICACHE_INVALID_WORD));
#endif
Jit->WriteExceptionExit();

View file

@ -143,9 +143,8 @@ void JitILAsmRoutineManager::Generate()
if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack))
SetJumpTarget(exit_vmem);
TEST(32, R(EAX), Imm32(0xFC));
FixupBranch notfound = J_CC(CC_NZ);
BSWAP(32, EAX);
TEST(32, R(EAX), R(EAX));
FixupBranch notfound = J_CC(CC_L);
//IDEA - we have 26 bits, why not just use offsets from base of code?
if (enableDebug)
{

View file

@ -17,8 +17,6 @@
#include <set>
#define JIT_OPCODE 0
class JitBase : public CPUCoreBase
{
protected:

View file

@ -198,7 +198,8 @@ bool JitBlock::ContainsAddress(u32 em_address)
{
blockCodePointers[block_num] = code_ptr;
JitBlock &b = blocks[block_num];
JitInterface::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num);
u32* icp = GetICachePtr(b.originalAddress);
*icp = block_num;
// Convert the logical address to a physical address for the block map
u32 pAddr = b.originalAddress & 0x1FFFFFFF;
@ -247,24 +248,22 @@ bool JitBlock::ContainsAddress(u32 em_address)
return blockCodePointers;
}
u32* JitBaseBlockCache::GetICachePtr(u32 addr)
{
if (addr & JIT_ICACHE_VMEM_BIT)
return (u32*)(jit->GetBlockCache()->iCacheVMEM + (addr & JIT_ICACHE_MASK));
else if (addr & JIT_ICACHE_EXRAM_BIT)
return (u32*)(jit->GetBlockCache()->iCacheEx + (addr & JIT_ICACHEEX_MASK));
else
return (u32*)(jit->GetBlockCache()->iCache + (addr & JIT_ICACHE_MASK));
}
int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr)
{
if (!blocks)
return -1;
u32 inst;
if (addr & JIT_ICACHE_VMEM_BIT)
{
inst = *(u32*)(iCacheVMEM + (addr & JIT_ICACHE_MASK));
}
else if (addr & JIT_ICACHE_EXRAM_BIT)
{
inst = *(u32*)(iCacheEx + (addr & JIT_ICACHEEX_MASK));
}
else
{
inst = *(u32*)(iCache + (addr & JIT_ICACHE_MASK));
}
inst = Common::swap32(inst);
inst = *GetICachePtr(addr);
if (inst & 0xfc000000) // definitely not a JIT block
return -1;
if ((int)inst >= num_blocks)
@ -364,7 +363,7 @@ bool JitBlock::ContainsAddress(u32 em_address)
return;
}
b.invalid = true;
JitInterface::Write_Opcode_JIT(b.originalAddress, JIT_ICACHE_INVALID_WORD);
*GetICachePtr(b.originalAddress) = JIT_ICACHE_INVALID_WORD;
UnlinkBlock(block_num);
@ -397,21 +396,7 @@ bool JitBlock::ContainsAddress(u32 em_address)
while (it2 != block_map.end() && it2->first.second < pAddr + length)
{
JitBlock &b = blocks[it2->second];
if (b.originalAddress & JIT_ICACHE_VMEM_BIT)
{
u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK;
memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4);
}
else if (b.originalAddress & JIT_ICACHE_EXRAM_BIT)
{
u32 cacheaddr = b.originalAddress & JIT_ICACHEEX_MASK;
memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4);
}
else
{
u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK;
memset(iCache + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4);
}
*GetICachePtr(b.originalAddress) = JIT_ICACHE_INVALID_WORD;
DestroyBlock(it2->second, true);
it2++;
}

View file

@ -27,8 +27,8 @@
#define JIT_ICACHE_EXRAM_BIT 0x10000000
#define JIT_ICACHE_VMEM_BIT 0x20000000
// this corresponds to opcode 5 which is invalid in PowerPC
#define JIT_ICACHE_INVALID_BYTE 0x14
#define JIT_ICACHE_INVALID_WORD 0x14141414
#define JIT_ICACHE_INVALID_BYTE 0x80
#define JIT_ICACHE_INVALID_WORD 0x80808080
struct JitBlock
{
@ -110,6 +110,8 @@ public:
u8 *iCacheEx;
u8 *iCacheVMEM;
u32* GetICachePtr(u32 addr);
// Fast way to get a block. Only works on the first ppc instruction of a block.
int GetBlockNumberFromStartAddress(u32 em_address);

View file

@ -209,41 +209,6 @@ namespace JitInterface
jit->GetBlockCache()->InvalidateICache(address, size);
}
// Memory functions
u32 Read_Opcode_JIT_Uncached(const u32 _Address)
{
u8* iCache;
u32 addr;
if (_Address & JIT_ICACHE_VMEM_BIT)
{
iCache = jit->GetBlockCache()->iCacheVMEM;
addr = _Address & JIT_ICACHE_MASK;
}
else if (_Address & JIT_ICACHE_EXRAM_BIT)
{
iCache = jit->GetBlockCache()->iCacheEx;
addr = _Address & JIT_ICACHEEX_MASK;
}
else
{
iCache = jit->GetBlockCache()->iCache;
addr = _Address & JIT_ICACHE_MASK;
}
u32 inst = *(u32*)(iCache + addr);
if (inst == JIT_ICACHE_INVALID_WORD)
{
u32 cache_block_start = addr & ~0x1f;
u32 mem_block_start = _Address & ~0x1f;
u8 *pMem = Memory::GetPointer(mem_block_start);
memcpy(iCache + cache_block_start, pMem, 32);
inst = *(u32*)(iCache + addr);
}
inst = Common::swap32(inst);
return inst;
}
u32 Read_Opcode_JIT(u32 _Address)
{
#ifdef FAST_ICACHE
@ -255,11 +220,12 @@ namespace JitInterface
return 0;
}
}
u32 inst = 0;
u32 inst;
// Bypass the icache for the external interrupt exception handler
// -- this is stupid, should respect HID0
if ( (_Address & 0x0FFFFF00) == 0x00000500 )
inst = Read_Opcode_JIT_Uncached(_Address);
inst = Memory::ReadUnchecked_U32(_Address);
else
inst = PowerPC::ppcState.iCache.ReadInstruction(_Address);
#else
@ -267,23 +233,6 @@ namespace JitInterface
#endif
return inst;
}
// WARNING! No checks!
// We assume that _Address is cached
void Write_Opcode_JIT(const u32 _Address, const u32 _Value)
{
if (_Address & JIT_ICACHE_VMEM_BIT)
{
*(u32*)(jit->GetBlockCache()->iCacheVMEM + (_Address & JIT_ICACHE_MASK)) = Common::swap32(_Value);
}
else if (_Address & JIT_ICACHE_EXRAM_BIT)
{
*(u32*)(jit->GetBlockCache()->iCacheEx + (_Address & JIT_ICACHEEX_MASK)) = Common::swap32(_Value);
}
else
*(u32*)(jit->GetBlockCache()->iCache + (_Address & JIT_ICACHE_MASK)) = Common::swap32(_Value);
}
void Shutdown()
{

View file

@ -22,8 +22,6 @@ namespace JitInterface
// used by JIT to read instructions
u32 Read_Opcode_JIT(const u32 _Address);
// used by JIT. uses iCacheJIT. Reads in the "Locked cache" mode
void Write_Opcode_JIT(const u32 _Address, const u32 _Value);
// Clearing CodeCache
void ClearCache();