summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorFiora <fioraaeterna@gmail.com>2014-09-11 03:59:40 -0700
committerFiora <fioraaeterna@gmail.com>2014-09-13 13:48:24 -0700
commit08ac10d00a06eb8d1f7fe7ad8249245b7883f9c4 (patch)
tree66f01035de688e72a0df712c21c2b2bab6f8005d /Source/Core
parent54129a8ca5bebb7d540132f061ab80d07adaadb4 (diff)
PPCAnalyst/JIT: add ability to easily toggle branch and carry merging
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.cpp2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp3
-rw-r--r--Source/Core/Core/PowerPC/PPCAnalyst.cpp15
-rw-r--r--Source/Core/Core/PowerPC/PPCAnalyst.h8
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),
};