From 08ac10d00a06eb8d1f7fe7ad8249245b7883f9c4 Mon Sep 17 00:00:00 2001 From: Fiora Date: Thu, 11 Sep 2014 03:59:40 -0700 Subject: [PATCH] PPCAnalyst/JIT: add ability to easily toggle branch and carry merging --- Source/Core/Core/PowerPC/Jit64/Jit.cpp | 2 ++ Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp | 3 +++ Source/Core/Core/PowerPC/PPCAnalyst.cpp | 15 +++++++++++---- Source/Core/Core/PowerPC/PPCAnalyst.h | 8 ++++++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 619217e4b6..4324e63ba9 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -177,6 +177,8 @@ void Jit64::Init() code_block.m_gpa = &js.gpa; code_block.m_fpa = &js.fpa; analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE); + analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_BRANCH_MERGE); + analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CARRY_MERGE); } void Jit64::ClearCache() diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index 203a5fae00..e86847ffc0 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -287,6 +287,9 @@ void Jit64::reg_imm(UGeckoInstruction inst) bool Jit64::CheckMergedBranch(int crf) { + if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_BRANCH_MERGE)) + return false; + const UGeckoInstruction& next = js.next_inst; return (((next.OPCD == 16 /* bcx */) || ((next.OPCD == 19) && (next.SUBOP10 == 528) /* bcctrx */) || diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index 2840b52fc9..d5eb128418 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -467,9 +467,13 @@ void PPCAnalyzer::ReorderInstructions(u32 instructions, CodeOp *code) { // For carry, bubble instructions *towards* each other; one direction often isn't enough // to get pairs like addc/adde next to each other. - ReorderInstructionsCore(instructions, code, true, REORDER_CARRY); - ReorderInstructionsCore(instructions, code, false, REORDER_CARRY); - ReorderInstructionsCore(instructions, code, false, REORDER_CMP); + if (HasOption(OPTION_CARRY_MERGE)) + { + ReorderInstructionsCore(instructions, code, true, REORDER_CARRY); + ReorderInstructionsCore(instructions, code, false, REORDER_CARRY); + } + if (HasOption(OPTION_BRANCH_MERGE)) + ReorderInstructionsCore(instructions, code, false, REORDER_CMP); } void PPCAnalyzer::SetInstructionStats(CodeBlock *block, CodeOp *code, GekkoOPInfo *opinfo, u32 index) @@ -509,7 +513,10 @@ void PPCAnalyzer::SetInstructionStats(CodeBlock *block, CodeOp *code, GekkoOPInf // We're going to try to avoid storing carry in XER if we can avoid it -- keep it in the x86 carry flag! // If the instruction reads CA but doesn't write it, we still need to store CA in XER; we can't // leave it in flags. - code->wantsCAInFlags = code->wantsCA && code->outputCA && opinfo->type == OPTYPE_INTEGER; + if (HasOption(OPTION_CARRY_MERGE)) + code->wantsCAInFlags = code->wantsCA && code->outputCA && opinfo->type == OPTYPE_INTEGER; + else + code->wantsCAInFlags = false; // mfspr/mtspr can affect/use XER, so be super careful here // we need to note specifically that mfspr needs CA in XER, not in the x86 carry flag diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.h b/Source/Core/Core/PowerPC/PPCAnalyst.h index 6be495f8f6..2238337710 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.h +++ b/Source/Core/Core/PowerPC/PPCAnalyst.h @@ -183,6 +183,14 @@ public: // Requires JIT support to work. // XXX: NOT COMPLETE OPTION_FORWARD_JUMP = (1 << 3), + + // Reorder compare/Rc instructions next to their associated branches and + // merge in the JIT (for common cases, anyway). + OPTION_BRANCH_MERGE = (1 << 4), + + // Reorder carry instructions next to their associated branches and pass + // carry flags in the x86 flags between them, instead of in XER. + OPTION_CARRY_MERGE = (1 << 5), };