mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 15:55:31 +01:00
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:
parent
2e32f11f03
commit
8962b9606b
@ -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
|
// Remove the invalid instruction from the icache, forcing a recompile
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
if (js.compilerPC & JIT_ICACHE_VMEM_BIT)
|
MOV(32, M(jit->GetBlockCache()->GetICachePtr(js.compilerPC)), Imm32(JIT_ICACHE_INVALID_WORD));
|
||||||
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));
|
|
||||||
#else
|
#else
|
||||||
if (js.compilerPC & JIT_ICACHE_VMEM_BIT)
|
MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICachePtr(js.compilerPC)));
|
||||||
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(32,MatR(RAX),Imm32(JIT_ICACHE_INVALID_WORD));
|
MOV(32,MatR(RAX),Imm32(JIT_ICACHE_INVALID_WORD));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -142,9 +142,8 @@ void Jit64AsmRoutineManager::Generate()
|
|||||||
if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack))
|
if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack))
|
||||||
SetJumpTarget(exit_vmem);
|
SetJumpTarget(exit_vmem);
|
||||||
|
|
||||||
TEST(32, R(EAX), Imm32(0xFC));
|
TEST(32, R(EAX), R(EAX));
|
||||||
FixupBranch notfound = J_CC(CC_NZ);
|
FixupBranch notfound = J_CC(CC_L);
|
||||||
BSWAP(32, EAX);
|
|
||||||
//IDEA - we have 26 bits, why not just use offsets from base of code?
|
//IDEA - we have 26 bits, why not just use offsets from base of code?
|
||||||
if (enableDebug)
|
if (enableDebug)
|
||||||
{
|
{
|
||||||
|
@ -1764,20 +1764,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit) {
|
|||||||
|
|
||||||
// Remove the invalid instruction from the icache, forcing a recompile
|
// Remove the invalid instruction from the icache, forcing a recompile
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
if (InstLoc & JIT_ICACHE_VMEM_BIT)
|
Jit->MOV(32, M(jit->GetBlockCache()->GetICachePtr(InstLoc)), Imm32(JIT_ICACHE_INVALID_WORD));
|
||||||
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));
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if (InstLoc & JIT_ICACHE_VMEM_BIT)
|
Jit->MOV(64, R(RAX), ImmPtr(jit->GetBlockCache()->GetICachePtr(InstLoc)));
|
||||||
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(32, MatR(RAX), Imm32(JIT_ICACHE_INVALID_WORD));
|
Jit->MOV(32, MatR(RAX), Imm32(JIT_ICACHE_INVALID_WORD));
|
||||||
#endif
|
#endif
|
||||||
Jit->WriteExceptionExit();
|
Jit->WriteExceptionExit();
|
||||||
|
@ -143,9 +143,8 @@ void JitILAsmRoutineManager::Generate()
|
|||||||
if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack))
|
if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack))
|
||||||
SetJumpTarget(exit_vmem);
|
SetJumpTarget(exit_vmem);
|
||||||
|
|
||||||
TEST(32, R(EAX), Imm32(0xFC));
|
TEST(32, R(EAX), R(EAX));
|
||||||
FixupBranch notfound = J_CC(CC_NZ);
|
FixupBranch notfound = J_CC(CC_L);
|
||||||
BSWAP(32, EAX);
|
|
||||||
//IDEA - we have 26 bits, why not just use offsets from base of code?
|
//IDEA - we have 26 bits, why not just use offsets from base of code?
|
||||||
if (enableDebug)
|
if (enableDebug)
|
||||||
{
|
{
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#define JIT_OPCODE 0
|
|
||||||
|
|
||||||
class JitBase : public CPUCoreBase
|
class JitBase : public CPUCoreBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -198,7 +198,8 @@ 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];
|
||||||
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
|
// Convert the logical address to a physical address for the block map
|
||||||
u32 pAddr = b.originalAddress & 0x1FFFFFFF;
|
u32 pAddr = b.originalAddress & 0x1FFFFFFF;
|
||||||
@ -247,24 +248,22 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
|||||||
return blockCodePointers;
|
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)
|
int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr)
|
||||||
{
|
{
|
||||||
if (!blocks)
|
if (!blocks)
|
||||||
return -1;
|
return -1;
|
||||||
u32 inst;
|
u32 inst;
|
||||||
if (addr & JIT_ICACHE_VMEM_BIT)
|
inst = *GetICachePtr(addr);
|
||||||
{
|
|
||||||
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);
|
|
||||||
if (inst & 0xfc000000) // definitely not a JIT block
|
if (inst & 0xfc000000) // definitely not a JIT block
|
||||||
return -1;
|
return -1;
|
||||||
if ((int)inst >= num_blocks)
|
if ((int)inst >= num_blocks)
|
||||||
@ -364,7 +363,7 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
b.invalid = true;
|
b.invalid = true;
|
||||||
JitInterface::Write_Opcode_JIT(b.originalAddress, JIT_ICACHE_INVALID_WORD);
|
*GetICachePtr(b.originalAddress) = JIT_ICACHE_INVALID_WORD;
|
||||||
|
|
||||||
UnlinkBlock(block_num);
|
UnlinkBlock(block_num);
|
||||||
|
|
||||||
@ -397,21 +396,7 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
|||||||
while (it2 != block_map.end() && it2->first.second < pAddr + length)
|
while (it2 != block_map.end() && it2->first.second < pAddr + length)
|
||||||
{
|
{
|
||||||
JitBlock &b = blocks[it2->second];
|
JitBlock &b = blocks[it2->second];
|
||||||
if (b.originalAddress & JIT_ICACHE_VMEM_BIT)
|
*GetICachePtr(b.originalAddress) = JIT_ICACHE_INVALID_WORD;
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
DestroyBlock(it2->second, true);
|
DestroyBlock(it2->second, true);
|
||||||
it2++;
|
it2++;
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
#define JIT_ICACHE_EXRAM_BIT 0x10000000
|
#define JIT_ICACHE_EXRAM_BIT 0x10000000
|
||||||
#define JIT_ICACHE_VMEM_BIT 0x20000000
|
#define JIT_ICACHE_VMEM_BIT 0x20000000
|
||||||
// this corresponds to opcode 5 which is invalid in PowerPC
|
// this corresponds to opcode 5 which is invalid in PowerPC
|
||||||
#define JIT_ICACHE_INVALID_BYTE 0x14
|
#define JIT_ICACHE_INVALID_BYTE 0x80
|
||||||
#define JIT_ICACHE_INVALID_WORD 0x14141414
|
#define JIT_ICACHE_INVALID_WORD 0x80808080
|
||||||
|
|
||||||
struct JitBlock
|
struct JitBlock
|
||||||
{
|
{
|
||||||
@ -110,6 +110,8 @@ public:
|
|||||||
u8 *iCacheEx;
|
u8 *iCacheEx;
|
||||||
u8 *iCacheVMEM;
|
u8 *iCacheVMEM;
|
||||||
|
|
||||||
|
u32* GetICachePtr(u32 addr);
|
||||||
|
|
||||||
// Fast way to get a block. Only works on the first ppc instruction of a block.
|
// Fast way to get a block. Only works on the first ppc instruction of a block.
|
||||||
int GetBlockNumberFromStartAddress(u32 em_address);
|
int GetBlockNumberFromStartAddress(u32 em_address);
|
||||||
|
|
||||||
|
@ -209,41 +209,6 @@ namespace JitInterface
|
|||||||
jit->GetBlockCache()->InvalidateICache(address, size);
|
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)
|
u32 Read_Opcode_JIT(u32 _Address)
|
||||||
{
|
{
|
||||||
#ifdef FAST_ICACHE
|
#ifdef FAST_ICACHE
|
||||||
@ -255,11 +220,12 @@ namespace JitInterface
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u32 inst = 0;
|
|
||||||
|
|
||||||
|
u32 inst;
|
||||||
// Bypass the icache for the external interrupt exception handler
|
// Bypass the icache for the external interrupt exception handler
|
||||||
|
// -- this is stupid, should respect HID0
|
||||||
if ( (_Address & 0x0FFFFF00) == 0x00000500 )
|
if ( (_Address & 0x0FFFFF00) == 0x00000500 )
|
||||||
inst = Read_Opcode_JIT_Uncached(_Address);
|
inst = Memory::ReadUnchecked_U32(_Address);
|
||||||
else
|
else
|
||||||
inst = PowerPC::ppcState.iCache.ReadInstruction(_Address);
|
inst = PowerPC::ppcState.iCache.ReadInstruction(_Address);
|
||||||
#else
|
#else
|
||||||
@ -267,23 +233,6 @@ namespace JitInterface
|
|||||||
#endif
|
#endif
|
||||||
return inst;
|
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()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
|
@ -22,8 +22,6 @@ namespace JitInterface
|
|||||||
|
|
||||||
// used by JIT to read instructions
|
// used by JIT to read instructions
|
||||||
u32 Read_Opcode_JIT(const u32 _Address);
|
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
|
// Clearing CodeCache
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user