Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #323 from Sonicadvance1/newer-ppcanalyst
[RFC] New PPCAnalyst class.
  • Loading branch information
Sonicadvance1 committed Apr 30, 2014
2 parents 1b581b7 + 8e1dfef commit c4221e8
Show file tree
Hide file tree
Showing 13 changed files with 522 additions and 465 deletions.
40 changes: 15 additions & 25 deletions Source/Core/Core/PowerPC/Jit64/Jit.cpp
Expand Up @@ -181,6 +181,11 @@ void Jit64::Init()

blocks.Init();
asm_routines.Init();

code_block.m_stats = &js.st;
code_block.m_gpa = &js.gpa;
code_block.m_fpa = &js.fpa;
analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE);
}

void Jit64::ClearCache()
Expand Down Expand Up @@ -404,9 +409,6 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
// Memory exception on instruction fetch
bool memory_exception = false;

// A broken block is a block that does not end in a branch
bool broken_block = false;

if (Core::g_CoreStartupParameter.bEnableDebugging)
{
// Comment out the following to disable breakpoints (speed-up)
Expand All @@ -433,7 +435,6 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
}
}

int size = 0;
js.firstFPInstructionFound = false;
js.isLastInstruction = false;
js.blockStart = em_address;
Expand All @@ -444,17 +445,12 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
jit->js.numLoadStoreInst = 0;
jit->js.numFloatingPointInst = 0;

u32 nextPC = em_address;
// Analyze the block, collect all instructions it is made of (including inlining,
// if that is enabled), reorder instructions for optimal performance, and join joinable instructions.
u32 nextPC = em_address;
u32 merged_addresses[32];
const int capacity_of_merged_addresses = sizeof(merged_addresses) / sizeof(merged_addresses[0]);
int size_of_merged_addresses = 0;
if (!memory_exception)
{
// If there is a memory exception inside a block (broken_block==true), compile up to that instruction.
nextPC = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses);
}
nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize);


PPCAnalyst::CodeOp *ops = code_buf->codebuffer;

Expand Down Expand Up @@ -499,27 +495,21 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc

js.downcountAmount = 0;
if (!Core::g_CoreStartupParameter.bEnableDebugging)
{
for (int i = 0; i < size_of_merged_addresses; ++i)
{
const u32 address = merged_addresses[i];
js.downcountAmount += PatchEngine::GetSpeedhackCycles(address);
}
}
js.downcountAmount += PatchEngine::GetSpeedhackCycles(code_block.m_address);

js.skipnext = false;
js.blockSize = size;
js.blockSize = code_block.m_num_instructions;
js.compilerPC = nextPC;
// Translate instructions
for (int i = 0; i < (int)size; i++)
for (u32 i = 0; i < code_block.m_num_instructions; i++)
{
js.compilerPC = ops[i].address;
js.op = &ops[i];
js.instructionNumber = i;
const GekkoOPInfo *opinfo = ops[i].opinfo;
js.downcountAmount += opinfo->numCycles;

if (i == (int)size - 1)
if (i == (code_block.m_num_instructions - 1))
{
// WARNING - cmp->branch merging will screw this up.
js.isLastInstruction = true;
Expand Down Expand Up @@ -706,7 +696,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
WriteExceptionExit();
}

if (broken_block)
if (code_block.m_broken)
{
gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);
Expand All @@ -715,10 +705,10 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc

b->flags = js.block_flags;
b->codeSize = (u32)(GetCodePtr() - normalEntry);
b->originalSize = size;
b->originalSize = code_block.m_num_instructions;

#ifdef JIT_LOG_X86
LogGeneratedX86(size, code_buf, normalEntry, b);
LogGeneratedX86(code_block.m_num_instructions, code_buf, normalEntry, b);
#endif

return normalEntry;
Expand Down
20 changes: 9 additions & 11 deletions Source/Core/Core/PowerPC/Jit64/Jit_Branch.cpp
Expand Up @@ -103,7 +103,6 @@ void Jit64::bcx(UGeckoInstruction inst)
JITDISABLE(bJITBranchOff)

// USES_CR
_assert_msg_(DYNA_REC, js.isLastInstruction, "bcx not last instruction of block");

gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);
Expand Down Expand Up @@ -142,7 +141,9 @@ void Jit64::bcx(UGeckoInstruction inst)
SetJumpTarget( pConditionDontBranch );
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
SetJumpTarget( pCTRDontBranch );
WriteExit(js.compilerPC + 4);

if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE))
WriteExit(js.compilerPC + 4);
}

void Jit64::bcctrx(UGeckoInstruction inst)
Expand Down Expand Up @@ -190,7 +191,9 @@ void Jit64::bcctrx(UGeckoInstruction inst)
WriteExitDestInEAX();
// Would really like to continue the block here, but it ends. TODO.
SetJumpTarget(b);
WriteExit(js.compilerPC + 4);

if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE))
WriteExit(js.compilerPC + 4);
}
}

Expand All @@ -199,13 +202,6 @@ void Jit64::bclrx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITBranchOff)

if (!js.isLastInstruction &&
(inst.BO & (1 << 4)) && (inst.BO & (1 << 2))) {
if (inst.LK)
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
return;
}

gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);

Expand Down Expand Up @@ -245,5 +241,7 @@ void Jit64::bclrx(UGeckoInstruction inst)
SetJumpTarget( pConditionDontBranch );
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
SetJumpTarget( pCTRDontBranch );
WriteExit(js.compilerPC + 4);

if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE))
WriteExit(js.compilerPC + 4);
}
20 changes: 13 additions & 7 deletions Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
Expand Up @@ -425,10 +425,12 @@ void Jit64::cmpXX(UGeckoInstruction inst)
}
else
{
WriteExit(js.next_compilerPC + 4);
if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE))
{
js.skipnext = true;
WriteExit(js.next_compilerPC + 4);
}
}

js.cancel = true;
}
}
else
Expand Down Expand Up @@ -535,9 +537,11 @@ void Jit64::cmpXX(UGeckoInstruction inst)
if (!!(4 & test_bit) == condition) SetJumpTarget(continue2);
if (!!(2 & test_bit) == condition) SetJumpTarget(continue1);

WriteExit(js.next_compilerPC + 4);

js.cancel = true;
if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE))
{
js.skipnext = true;
WriteExit(js.next_compilerPC + 4);
}
}
}

Expand Down Expand Up @@ -2229,5 +2233,7 @@ void Jit64::twx(UGeckoInstruction inst)
SetJumpTarget(exit3);
SetJumpTarget(exit4);
SetJumpTarget(exit5);
WriteExit(js.compilerPC + 4);

if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE))
WriteExit(js.compilerPC + 4);
}
41 changes: 14 additions & 27 deletions Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp
Expand Up @@ -268,6 +268,10 @@ void JitIL::Init()
blocks.Init();
asm_routines.Init();

code_block.m_stats = &js.st;
code_block.m_gpa = &js.gpa;
code_block.m_fpa = &js.fpa;

if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
JitILProfiler::Init();
}
Expand Down Expand Up @@ -500,9 +504,6 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
// Memory exception on instruction fetch
bool memory_exception = false;

// A broken block is a block that does not end in a branch
bool broken_block = false;

if (Core::g_CoreStartupParameter.bEnableDebugging)
{
// Comment out the following to disable breakpoints (speed-up)
Expand All @@ -529,7 +530,6 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
}
}

int size = 0;
js.isLastInstruction = false;
js.blockStart = em_address;
js.fifoBytesThisBlock = 0;
Expand All @@ -538,19 +538,12 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
jit->js.numLoadStoreInst = 0;
jit->js.numFloatingPointInst = 0;

u32 nextPC = em_address;
// Analyze the block, collect all instructions it is made of (including inlining,
// if that is enabled), reorder instructions for optimal performance, and join joinable instructions.
u32 exitAddress = em_address;

u32 merged_addresses[32];
const int capacity_of_merged_addresses = sizeof(merged_addresses) / sizeof(merged_addresses[0]);
int size_of_merged_addresses = 0;
if (!memory_exception)
{
// If there is a memory exception inside a block (broken_block==true), compile up to that instruction.
// TODO
exitAddress = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses);
}
nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize);

PPCAnalyst::CodeOp *ops = code_buf->codebuffer;

const u8 *start = AlignCode4(); // TODO: Test if this or AlignCode16 make a difference from GetCodePtr
Expand Down Expand Up @@ -586,7 +579,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILOutputIR)
{
// For profiling and IR Writer
for (int i = 0; i < (int)size; i++)
for (u32 i = 0; i < code_block.m_num_instructions; i++)
{
const u64 inst = ops[i].inst.hex;
// Ported from boost::hash
Expand All @@ -606,24 +599,18 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc

js.downcountAmount = 0;
if (!Core::g_CoreStartupParameter.bEnableDebugging)
{
for (int i = 0; i < size_of_merged_addresses; ++i)
{
const u32 address = merged_addresses[i];
js.downcountAmount += PatchEngine::GetSpeedhackCycles(address);
}
}
js.downcountAmount += PatchEngine::GetSpeedhackCycles(code_block.m_address);

// Translate instructions
for (int i = 0; i < (int)size; i++)
for (u32 i = 0; i < code_block.m_num_instructions; i++)
{
js.compilerPC = ops[i].address;
js.op = &ops[i];
js.instructionNumber = i;
const GekkoOPInfo *opinfo = GetOpInfo(ops[i].inst);
js.downcountAmount += opinfo->numCycles;

if (i == (int)size - 1)
if (i == (code_block.m_num_instructions - 1))
{
js.isLastInstruction = true;
js.next_inst = 0;
Expand Down Expand Up @@ -708,13 +695,13 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
}

// Perform actual code generation
WriteCode(exitAddress);
WriteCode(nextPC);

b->codeSize = (u32)(GetCodePtr() - normalEntry);
b->originalSize = size;
b->originalSize = code_block.m_num_instructions;

#ifdef JIT_LOG_X86
LogGeneratedX86(size, code_buf, normalEntry, b);
LogGeneratedX86(code_block.m_num_instructions, code_buf, normalEntry, b);
#endif

if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILOutputIR)
Expand Down

0 comments on commit c4221e8

Please sign in to comment.