Support the new PPCAnalyst class in JIT64.
Implements support for OPTION_CONDITIONAL_CONTINUE in JIT64.
This commit is contained in:
parent
ad167e7b52
commit
40c317d1d4
|
@ -181,6 +181,11 @@ void Jit64::Init()
|
||||||
|
|
||||||
blocks.Init();
|
blocks.Init();
|
||||||
asm_routines.Init();
|
asm_routines.Init();
|
||||||
|
|
||||||
|
code_block.m_stats = &js.st;
|
||||||
|
code_block.m_gpa = &js.gpa;
|
||||||
|
code_block.m_fpa = &js.fpa;
|
||||||
|
analyser.SetOption(PPCAnalyst::PPCAnalyser::OPTION_CONDITIONAL_CONTINUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::ClearCache()
|
void Jit64::ClearCache()
|
||||||
|
@ -404,9 +409,6 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
// Memory exception on instruction fetch
|
// Memory exception on instruction fetch
|
||||||
bool memory_exception = false;
|
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)
|
if (Core::g_CoreStartupParameter.bEnableDebugging)
|
||||||
{
|
{
|
||||||
// Comment out the following to disable breakpoints (speed-up)
|
// Comment out the following to disable breakpoints (speed-up)
|
||||||
|
@ -433,7 +435,6 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
js.firstFPInstructionFound = false;
|
js.firstFPInstructionFound = false;
|
||||||
js.isLastInstruction = false;
|
js.isLastInstruction = false;
|
||||||
js.blockStart = em_address;
|
js.blockStart = em_address;
|
||||||
|
@ -444,17 +445,12 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
jit->js.numLoadStoreInst = 0;
|
jit->js.numLoadStoreInst = 0;
|
||||||
jit->js.numFloatingPointInst = 0;
|
jit->js.numFloatingPointInst = 0;
|
||||||
|
|
||||||
|
u32 nextPC = em_address;
|
||||||
// Analyze the block, collect all instructions it is made of (including inlining,
|
// 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.
|
// 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 (!memory_exception)
|
||||||
{
|
nextPC = analyser.Analyse(em_address, &code_block, code_buf, blockSize);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
PPCAnalyst::CodeOp *ops = code_buf->codebuffer;
|
PPCAnalyst::CodeOp *ops = code_buf->codebuffer;
|
||||||
|
|
||||||
|
@ -499,19 +495,13 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
|
|
||||||
js.downcountAmount = 0;
|
js.downcountAmount = 0;
|
||||||
if (!Core::g_CoreStartupParameter.bEnableDebugging)
|
if (!Core::g_CoreStartupParameter.bEnableDebugging)
|
||||||
{
|
js.downcountAmount += PatchEngine::GetSpeedhackCycles(code_block.m_address);
|
||||||
for (int i = 0; i < size_of_merged_addresses; ++i)
|
|
||||||
{
|
|
||||||
const u32 address = merged_addresses[i];
|
|
||||||
js.downcountAmount += PatchEngine::GetSpeedhackCycles(address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
js.skipnext = false;
|
js.skipnext = false;
|
||||||
js.blockSize = size;
|
js.blockSize = code_block.m_instructions;
|
||||||
js.compilerPC = nextPC;
|
js.compilerPC = nextPC;
|
||||||
// Translate instructions
|
// Translate instructions
|
||||||
for (int i = 0; i < (int)size; i++)
|
for (u32 i = 0; i < code_block.m_instructions; i++)
|
||||||
{
|
{
|
||||||
js.compilerPC = ops[i].address;
|
js.compilerPC = ops[i].address;
|
||||||
js.op = &ops[i];
|
js.op = &ops[i];
|
||||||
|
@ -519,7 +509,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
const GekkoOPInfo *opinfo = ops[i].opinfo;
|
const GekkoOPInfo *opinfo = ops[i].opinfo;
|
||||||
js.downcountAmount += opinfo->numCycles;
|
js.downcountAmount += opinfo->numCycles;
|
||||||
|
|
||||||
if (i == (int)size - 1)
|
if (i == (code_block.m_instructions - 1))
|
||||||
{
|
{
|
||||||
// WARNING - cmp->branch merging will screw this up.
|
// WARNING - cmp->branch merging will screw this up.
|
||||||
js.isLastInstruction = true;
|
js.isLastInstruction = true;
|
||||||
|
@ -706,7 +696,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
WriteExceptionExit();
|
WriteExceptionExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (broken_block)
|
if (code_block.m_broken)
|
||||||
{
|
{
|
||||||
gpr.Flush(FLUSH_ALL);
|
gpr.Flush(FLUSH_ALL);
|
||||||
fpr.Flush(FLUSH_ALL);
|
fpr.Flush(FLUSH_ALL);
|
||||||
|
@ -715,10 +705,10 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
|
|
||||||
b->flags = js.block_flags;
|
b->flags = js.block_flags;
|
||||||
b->codeSize = (u32)(GetCodePtr() - normalEntry);
|
b->codeSize = (u32)(GetCodePtr() - normalEntry);
|
||||||
b->originalSize = size;
|
b->originalSize = code_block.m_instructions;
|
||||||
|
|
||||||
#ifdef JIT_LOG_X86
|
#ifdef JIT_LOG_X86
|
||||||
LogGeneratedX86(size, code_buf, normalEntry, b);
|
LogGeneratedX86(code_block.m_instructions, code_buf, normalEntry, b);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return normalEntry;
|
return normalEntry;
|
||||||
|
|
|
@ -103,7 +103,6 @@ void Jit64::bcx(UGeckoInstruction inst)
|
||||||
JITDISABLE(bJITBranchOff)
|
JITDISABLE(bJITBranchOff)
|
||||||
|
|
||||||
// USES_CR
|
// USES_CR
|
||||||
_assert_msg_(DYNA_REC, js.isLastInstruction, "bcx not last instruction of block");
|
|
||||||
|
|
||||||
gpr.Flush(FLUSH_ALL);
|
gpr.Flush(FLUSH_ALL);
|
||||||
fpr.Flush(FLUSH_ALL);
|
fpr.Flush(FLUSH_ALL);
|
||||||
|
@ -142,6 +141,8 @@ void Jit64::bcx(UGeckoInstruction inst)
|
||||||
SetJumpTarget( pConditionDontBranch );
|
SetJumpTarget( pConditionDontBranch );
|
||||||
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
SetJumpTarget( pCTRDontBranch );
|
SetJumpTarget( pCTRDontBranch );
|
||||||
|
|
||||||
|
if (!analyser.HasOption(PPCAnalyst::PPCAnalyser::OPTION_CONDITIONAL_CONTINUE))
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +191,8 @@ void Jit64::bcctrx(UGeckoInstruction inst)
|
||||||
WriteExitDestInEAX();
|
WriteExitDestInEAX();
|
||||||
// Would really like to continue the block here, but it ends. TODO.
|
// Would really like to continue the block here, but it ends. TODO.
|
||||||
SetJumpTarget(b);
|
SetJumpTarget(b);
|
||||||
|
|
||||||
|
if (!analyser.HasOption(PPCAnalyst::PPCAnalyser::OPTION_CONDITIONAL_CONTINUE))
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,13 +202,6 @@ void Jit64::bclrx(UGeckoInstruction inst)
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITBranchOff)
|
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);
|
gpr.Flush(FLUSH_ALL);
|
||||||
fpr.Flush(FLUSH_ALL);
|
fpr.Flush(FLUSH_ALL);
|
||||||
|
|
||||||
|
@ -245,5 +241,7 @@ void Jit64::bclrx(UGeckoInstruction inst)
|
||||||
SetJumpTarget( pConditionDontBranch );
|
SetJumpTarget( pConditionDontBranch );
|
||||||
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
SetJumpTarget( pCTRDontBranch );
|
SetJumpTarget( pCTRDontBranch );
|
||||||
|
|
||||||
|
if (!analyser.HasOption(PPCAnalyst::PPCAnalyser::OPTION_CONDITIONAL_CONTINUE))
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -425,10 +425,12 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!analyser.HasOption(PPCAnalyst::PPCAnalyser::OPTION_CONDITIONAL_CONTINUE))
|
||||||
|
{
|
||||||
|
js.skipnext = true;
|
||||||
WriteExit(js.next_compilerPC + 4);
|
WriteExit(js.next_compilerPC + 4);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
js.cancel = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -535,9 +537,11 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
||||||
if (!!(4 & test_bit) == condition) SetJumpTarget(continue2);
|
if (!!(4 & test_bit) == condition) SetJumpTarget(continue2);
|
||||||
if (!!(2 & test_bit) == condition) SetJumpTarget(continue1);
|
if (!!(2 & test_bit) == condition) SetJumpTarget(continue1);
|
||||||
|
|
||||||
|
if (!analyser.HasOption(PPCAnalyst::PPCAnalyser::OPTION_CONDITIONAL_CONTINUE))
|
||||||
|
{
|
||||||
|
js.skipnext = true;
|
||||||
WriteExit(js.next_compilerPC + 4);
|
WriteExit(js.next_compilerPC + 4);
|
||||||
|
}
|
||||||
js.cancel = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2229,5 +2233,7 @@ void Jit64::twx(UGeckoInstruction inst)
|
||||||
SetJumpTarget(exit3);
|
SetJumpTarget(exit3);
|
||||||
SetJumpTarget(exit4);
|
SetJumpTarget(exit4);
|
||||||
SetJumpTarget(exit5);
|
SetJumpTarget(exit5);
|
||||||
|
|
||||||
|
if (!analyser.HasOption(PPCAnalyst::PPCAnalyser::OPTION_CONDITIONAL_CONTINUE))
|
||||||
WriteExit(js.compilerPC + 4);
|
WriteExit(js.compilerPC + 4);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue