JIT: generic branch merging

Why merge just cmps and rlwinm when we can merge ALL the branches?
This commit is contained in:
Fiora
2014-09-24 12:34:18 -07:00
parent 0b6ec44e42
commit bfab5f1e91
3 changed files with 174 additions and 257 deletions
+3 -1
View File
@@ -118,13 +118,15 @@ public:
void FinalizeCarryOverflow(bool oe, bool inv = false);
void FinalizeCarry(Gen::CCFlags cond);
void FinalizeCarry(bool ca);
void ComputeRC(const Gen::OpArg & arg);
void ComputeRC(const Gen::OpArg & arg, bool needs_test = true, bool needs_sext = true);
// Use to extract bytes from a register using the regcache. offset is in bytes.
Gen::OpArg ExtractFromReg(int reg, int offset);
void AndWithMask(Gen::X64Reg reg, u32 mask);
bool CheckMergedBranch(int crf);
void DoMergedBranch();
void DoMergedBranchCondition();
void DoMergedBranchImmediate(s64 val);
// Reads a given bit of a given CR register part.
void GetCRFieldBit(int field, int bit, Gen::X64Reg out, bool negate = false);
File diff suppressed because it is too large Load Diff
+2 -7
View File
@@ -407,11 +407,6 @@ static bool isCmp(const CodeOp& a)
return (a.inst.OPCD == 10 || a.inst.OPCD == 11) || (a.inst.OPCD == 31 && (a.inst.SUBOP10 == 0 || a.inst.SUBOP10 == 32));
}
static bool isRlwinm_rc(const CodeOp& a)
{
return a.inst.OPCD == 21 && a.inst.Rc;
}
static bool isCarryOp(const CodeOp& a)
{
return (a.opinfo->flags & FL_SET_CA) && !(a.opinfo->flags & FL_SET_OE) && a.opinfo->type == OPTYPE_INTEGER;
@@ -437,7 +432,7 @@ void PPCAnalyzer::ReorderInstructionsCore(u32 instructions, CodeOp* code, bool r
CodeOp &b = code[i + increment];
// Reorder integer compares, rlwinm., and carry-affecting ops
// (if we add more merged branch instructions, add them here!)
if ((type == REORDER_CARRY && isCarryOp(a)) || (type == REORDER_CMP && (isCmp(a) || isRlwinm_rc(a))))
if ((type == REORDER_CARRY && isCarryOp(a)) || (type == REORDER_CMP && (isCmp(a) || a.outputCR0)))
{
// once we're next to a carry instruction, don't move away!
if (type == REORDER_CARRY && i != start)
@@ -469,8 +464,8 @@ void PPCAnalyzer::ReorderInstructions(u32 instructions, CodeOp *code)
// to get pairs like addc/adde next to each other.
if (HasOption(OPTION_CARRY_MERGE))
{
ReorderInstructionsCore(instructions, code, true, REORDER_CARRY);
ReorderInstructionsCore(instructions, code, false, REORDER_CARRY);
ReorderInstructionsCore(instructions, code, true, REORDER_CARRY);
}
if (HasOption(OPTION_BRANCH_MERGE))
ReorderInstructionsCore(instructions, code, false, REORDER_CMP);