mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-24 00:29:57 +00:00
Some JIT cleanup
This commit is contained in:
parent
f275607ae1
commit
8a904fe478
@ -169,7 +169,8 @@ void Jit::Compile(u32 em_address)
|
||||
|
||||
int block_num = blocks.AllocateBlock(em_address);
|
||||
ArmJitBlock *b = blocks.GetBlock(block_num);
|
||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, b));
|
||||
DoJit(em_address, b);
|
||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink);
|
||||
|
||||
// Drat. The VFPU hit an uneaten prefix at the end of a block.
|
||||
if (js.startDefaultPrefix && js.MayHavePrefix())
|
||||
|
@ -160,10 +160,10 @@ int ArmJitBlockCache::AllocateBlock(u32 em_address)
|
||||
return num_blocks - 1;
|
||||
}
|
||||
|
||||
void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr)
|
||||
void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link)
|
||||
{
|
||||
blockCodePointers[block_num] = code_ptr;
|
||||
ArmJitBlock &b = blocks[block_num];
|
||||
blockCodePointers[block_num] = b.normalEntry;
|
||||
|
||||
b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress);
|
||||
u32 opcode = MIPS_MAKE_EMUHACK(0, block_num);
|
||||
@ -189,7 +189,7 @@ void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *c
|
||||
#if defined USE_OPROFILE && USE_OPROFILE
|
||||
char buf[100];
|
||||
sprintf(buf, "EmuCode%x", b.originalAddress);
|
||||
const u8* blockStart = blockCodePointers[block_num];
|
||||
const u8* blockStart = blocks[block_num].checkedEntry;
|
||||
op_write_native_code(agent, buf, (uint64_t)blockStart,
|
||||
blockStart, b.codeSize);
|
||||
#endif
|
||||
@ -201,7 +201,7 @@ void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *c
|
||||
jmethod.method_id = iJIT_GetNewMethodID();
|
||||
jmethod.class_file_name = "";
|
||||
jmethod.source_file_name = __FILE__;
|
||||
jmethod.method_load_address = (void*)blockCodePointers[block_num];
|
||||
jmethod.method_load_address = (void*)blocks[block_num].checkedEntry;
|
||||
jmethod.method_size = b.codeSize;
|
||||
jmethod.line_number_size = 0;
|
||||
jmethod.method_name = b.blockName;
|
||||
@ -246,29 +246,6 @@ u32 ArmJitBlockCache::GetOriginalFirstOp(int block_num)
|
||||
return blocks[block_num].originalFirstOpcode;
|
||||
}
|
||||
|
||||
CompiledCode ArmJitBlockCache::GetCompiledCodeFromBlock(int block_num)
|
||||
{
|
||||
return (CompiledCode)blockCodePointers[block_num];
|
||||
}
|
||||
|
||||
std::string ArmJitBlockCache::GetCompiledDisassembly(int block_num)
|
||||
{
|
||||
/*
|
||||
std::string buf;
|
||||
const u8 *ptr = blockCodePointers[block_num];
|
||||
|
||||
while (ptr < blockCodePointers[block_num] + blocks[block_num].codeSize)
|
||||
{
|
||||
int len;
|
||||
buf += std::string(disasmx86((unsigned char*)ptr, 0, &len)) + "\n";
|
||||
ptr += len;
|
||||
}*/
|
||||
return "No ARM disassembler";
|
||||
}
|
||||
|
||||
|
||||
//Make sure to have as many blocks as possible compiled before calling this
|
||||
//It's O(1), so it's fast :)
|
||||
void ArmJitBlockCache::LinkBlockExits(int i)
|
||||
{
|
||||
ArmJitBlock &b = blocks[i];
|
||||
@ -328,6 +305,10 @@ void ArmJitBlockCache::UnlinkBlock(int i)
|
||||
}
|
||||
}
|
||||
|
||||
u32 ArmJitBlockCache::GetEmuHackOpForBlock(int blockNum) const {
|
||||
return (MIPS_EMUHACK_OPCODE | blockNum);
|
||||
}
|
||||
|
||||
void ArmJitBlockCache::DestroyBlock(int block_num, bool invalidate)
|
||||
{
|
||||
if (block_num < 0 || block_num >= num_blocks)
|
||||
@ -343,12 +324,14 @@ void ArmJitBlockCache::DestroyBlock(int block_num, bool invalidate)
|
||||
return;
|
||||
}
|
||||
b.invalid = true;
|
||||
if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == (MIPS_EMUHACK_OPCODE | block_num))
|
||||
if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == GetEmuHackOpForBlock(block_num))
|
||||
Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress);
|
||||
|
||||
UnlinkBlock(block_num);
|
||||
|
||||
b.normalEntry = 0;
|
||||
// TODO: remove
|
||||
blockCodePointers[block_num] = 0;
|
||||
|
||||
// Send anyone who tries to run this block back to the dispatcher.
|
||||
// Not entirely ideal, but .. pretty good.
|
||||
// I hope there's enough space...
|
||||
|
@ -30,17 +30,6 @@
|
||||
// emulate CPU with unlimited instruction cache
|
||||
// the only way to invalidate a region is the "icbi" instruction
|
||||
|
||||
#define JIT_ICACHE_SIZE 0x2000000
|
||||
#define JIT_ICACHE_MASK 0x1ffffff
|
||||
#define JIT_ICACHEEX_SIZE 0x4000000
|
||||
#define JIT_ICACHEEX_MASK 0x3ffffff
|
||||
#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_OPCODE 0xFFCCCCCC // yeah this ain't gonna work
|
||||
|
||||
struct ArmJitBlock
|
||||
{
|
||||
@ -85,7 +74,7 @@ public:
|
||||
MAX_NUM_BLOCKS(0) { }
|
||||
~ArmJitBlockCache();
|
||||
int AllocateBlock(u32 em_address);
|
||||
void FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr);
|
||||
void FinalizeBlock(int block_num, bool block_link);
|
||||
|
||||
void Clear();
|
||||
void ClearSafe();
|
||||
@ -110,18 +99,18 @@ public:
|
||||
void GetBlockNumbersFromAddress(u32 em_address, std::vector<int> *block_numbers);
|
||||
|
||||
u32 GetOriginalFirstOp(int block_num);
|
||||
CompiledCode GetCompiledCodeFromBlock(int block_num);
|
||||
|
||||
// DOES NOT WORK CORRECTLY WITH INLINING
|
||||
void InvalidateICache(u32 address, const u32 length);
|
||||
void DestroyBlock(int block_num, bool invalidate);
|
||||
|
||||
std::string GetCompiledDisassembly(int block_num);
|
||||
|
||||
// Not currently used
|
||||
//void DestroyBlocksWithFlag(BlockFlag death_flag);
|
||||
|
||||
private:
|
||||
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
|
||||
void LinkBlockExits(int i);
|
||||
void LinkBlock(int i);
|
||||
void UnlinkBlock(int i);
|
||||
u32 GetEmuHackOpForBlock(int blockNum) const;
|
||||
|
||||
MIPSState *mips;
|
||||
const u8 **blockCodePointers;
|
||||
ArmJitBlock *blocks;
|
||||
@ -130,9 +119,4 @@ private:
|
||||
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
|
||||
|
||||
int MAX_NUM_BLOCKS;
|
||||
|
||||
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
|
||||
void LinkBlockExits(int i);
|
||||
void LinkBlock(int i);
|
||||
void UnlinkBlock(int i);
|
||||
};
|
||||
|
@ -220,7 +220,8 @@ void Jit::Compile(u32 em_address)
|
||||
|
||||
int block_num = blocks.AllocateBlock(em_address);
|
||||
JitBlock *b = blocks.GetBlock(block_num);
|
||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, b));
|
||||
DoJit(em_address, b);
|
||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink);
|
||||
|
||||
// Drat. The VFPU hit an uneaten prefix at the end of a block.
|
||||
if (js.startDefaultPrefix && js.MayHavePrefix())
|
||||
|
@ -173,10 +173,10 @@ int JitBlockCache::AllocateBlock(u32 em_address)
|
||||
return num_blocks - 1;
|
||||
}
|
||||
|
||||
void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr)
|
||||
void JitBlockCache::FinalizeBlock(int block_num, bool block_link)
|
||||
{
|
||||
blockCodePointers[block_num] = code_ptr;
|
||||
JitBlock &b = blocks[block_num];
|
||||
blockCodePointers[block_num] = b.normalEntry;
|
||||
|
||||
b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress);
|
||||
u32 opcode = MIPS_MAKE_EMUHACK(0, block_num);
|
||||
@ -202,9 +202,8 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code
|
||||
#if defined USE_OPROFILE && USE_OPROFILE
|
||||
char buf[100];
|
||||
sprintf(buf, "EmuCode%x", b.originalAddress);
|
||||
const u8* blockStart = blockCodePointers[block_num];
|
||||
op_write_native_code(agent, buf, (uint64_t)blockStart,
|
||||
blockStart, b.codeSize);
|
||||
const u8* blockStart = blocks[block_num].checkedEntry;
|
||||
op_write_native_code(agent, buf, (uint64_t)blockStart, blockStart, b.codeSize);
|
||||
#endif
|
||||
|
||||
#ifdef USE_VTUNE
|
||||
@ -214,7 +213,7 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code
|
||||
jmethod.method_id = iJIT_GetNewMethodID();
|
||||
jmethod.class_file_name = "";
|
||||
jmethod.source_file_name = __FILE__;
|
||||
jmethod.method_load_address = (void*)blockCodePointers[block_num];
|
||||
jmethod.method_load_address = (void*)blocks[block_num].checkedEntry;
|
||||
jmethod.method_size = b.codeSize;
|
||||
jmethod.line_number_size = 0;
|
||||
jmethod.method_name = b.blockName;
|
||||
@ -259,19 +258,6 @@ u32 JitBlockCache::GetOriginalFirstOp(int block_num)
|
||||
return blocks[block_num].originalFirstOpcode;
|
||||
}
|
||||
|
||||
CompiledCode JitBlockCache::GetCompiledCodeFromBlock(int block_num)
|
||||
{
|
||||
return (CompiledCode)blockCodePointers[block_num];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Block linker
|
||||
//Make sure to have as many blocks as possible compiled before calling this
|
||||
//It's O(N), so it's fast :)
|
||||
//Can be faster by doing a queue for blocks to link up, and only process those
|
||||
//Should probably be done
|
||||
|
||||
void JitBlockCache::LinkBlockExits(int i)
|
||||
{
|
||||
JitBlock &b = blocks[i];
|
||||
@ -330,6 +316,10 @@ void JitBlockCache::UnlinkBlock(int i)
|
||||
}
|
||||
}
|
||||
|
||||
u32 JitBlockCache::GetEmuHackOpForBlock(int blockNum) {
|
||||
return (MIPS_EMUHACK_OPCODE | blockNum);
|
||||
}
|
||||
|
||||
void JitBlockCache::DestroyBlock(int block_num, bool invalidate)
|
||||
{
|
||||
if (block_num < 0 || block_num >= num_blocks)
|
||||
@ -345,7 +335,7 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate)
|
||||
return;
|
||||
}
|
||||
b.invalid = true;
|
||||
if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == (MIPS_EMUHACK_OPCODE | block_num))
|
||||
if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == GetEmuHackOpForBlock(block_num))
|
||||
Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress);
|
||||
|
||||
UnlinkBlock(block_num);
|
||||
@ -356,13 +346,6 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate)
|
||||
XEmitter emit((u8 *)b.checkedEntry);
|
||||
emit.MOV(32, M(&mips->pc), Imm32(b.originalAddress));
|
||||
emit.JMP(MIPSComp::jit->Asm().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, const u32 length)
|
||||
|
@ -79,20 +79,6 @@ typedef void (*CompiledCode)();
|
||||
|
||||
class JitBlockCache
|
||||
{
|
||||
MIPSState *mips;
|
||||
const u8 **blockCodePointers;
|
||||
JitBlock *blocks;
|
||||
int num_blocks;
|
||||
std::multimap<u32, int> links_to;
|
||||
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
|
||||
|
||||
int MAX_NUM_BLOCKS;
|
||||
|
||||
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
|
||||
void LinkBlockExits(int i);
|
||||
void LinkBlock(int i);
|
||||
void UnlinkBlock(int i);
|
||||
|
||||
public:
|
||||
JitBlockCache(MIPSState *mips_) :
|
||||
mips(mips_), blockCodePointers(0), blocks(0), num_blocks(0),
|
||||
@ -100,7 +86,7 @@ public:
|
||||
~JitBlockCache();
|
||||
|
||||
int AllocateBlock(u32 em_address);
|
||||
void FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr);
|
||||
void FinalizeBlock(int block_num, bool block_link);
|
||||
|
||||
void Clear();
|
||||
void Init();
|
||||
@ -124,12 +110,26 @@ public:
|
||||
void GetBlockNumbersFromAddress(u32 em_address, std::vector<int> *block_numbers);
|
||||
|
||||
u32 GetOriginalFirstOp(int block_num);
|
||||
CompiledCode GetCompiledCodeFromBlock(int block_num);
|
||||
|
||||
// DOES NOT WORK CORRECTLY WITH JIT INLINING
|
||||
void InvalidateICache(u32 address, const u32 length);
|
||||
void DestroyBlock(int block_num, bool invalidate);
|
||||
|
||||
// Not currently used
|
||||
//void DestroyBlocksWithFlag(BlockFlag death_flag);
|
||||
private:
|
||||
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
|
||||
void LinkBlockExits(int i);
|
||||
void LinkBlock(int i);
|
||||
void UnlinkBlock(int i);
|
||||
|
||||
u32 GetEmuHackOpForBlock(int block_num);
|
||||
|
||||
MIPSState *mips;
|
||||
const u8 **blockCodePointers;
|
||||
JitBlock *blocks;
|
||||
int num_blocks;
|
||||
std::multimap<u32, int> links_to;
|
||||
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
|
||||
|
||||
int MAX_NUM_BLOCKS;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user