mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
PPCAnalyst: Allow more reordering of CR operations
This is possible with the improved CR analysis implemented in the previous commits.
This commit is contained in:
@ -224,9 +224,7 @@ bool PPCAnalyzer::CanSwapAdjacentOps(const CodeOp& a, const CodeOp& b) const
|
|||||||
return false;
|
return false;
|
||||||
if (a_flags & (FL_ENDBLOCK | FL_TIMER | FL_EVIL | FL_SET_OE))
|
if (a_flags & (FL_ENDBLOCK | FL_TIMER | FL_EVIL | FL_SET_OE))
|
||||||
return false;
|
return false;
|
||||||
if (b_flags & (FL_SET_CRx | FL_ENDBLOCK | FL_TIMER | FL_EVIL | FL_SET_OE))
|
if (b_flags & (FL_ENDBLOCK | FL_TIMER | FL_EVIL | FL_SET_OE))
|
||||||
return false;
|
|
||||||
if ((b_flags & (FL_RC_BIT | FL_RC_BIT_F)) && (b.inst.Rc))
|
|
||||||
return false;
|
return false;
|
||||||
if ((a_flags & (FL_SET_CA | FL_READ_CA)) && (b_flags & (FL_SET_CA | FL_READ_CA)))
|
if ((a_flags & (FL_SET_CA | FL_READ_CA)) && (b_flags & (FL_SET_CA | FL_READ_CA)))
|
||||||
return false;
|
return false;
|
||||||
@ -249,16 +247,22 @@ bool PPCAnalyzer::CanSwapAdjacentOps(const CodeOp& a, const CodeOp& b) const
|
|||||||
// Check that we have no register collisions.
|
// Check that we have no register collisions.
|
||||||
// That is, check that none of b's outputs matches any of a's inputs,
|
// That is, check that none of b's outputs matches any of a's inputs,
|
||||||
// and that none of a's outputs matches any of b's inputs.
|
// and that none of a's outputs matches any of b's inputs.
|
||||||
// The latter does not apply if a is a cmp, of course, but doesn't hurt to check.
|
|
||||||
// register collision: b outputs to one of a's inputs
|
// register collision: b outputs to one of a's inputs
|
||||||
if (b.regsOut & a.regsIn)
|
if (b.regsOut & a.regsIn)
|
||||||
return false;
|
return false;
|
||||||
|
if (b.crOut & a.crIn)
|
||||||
|
return false;
|
||||||
// register collision: a outputs to one of b's inputs
|
// register collision: a outputs to one of b's inputs
|
||||||
if (a.regsOut & b.regsIn)
|
if (a.regsOut & b.regsIn)
|
||||||
return false;
|
return false;
|
||||||
|
if (a.crOut & b.crIn)
|
||||||
|
return false;
|
||||||
// register collision: b outputs to one of a's outputs (overwriting it)
|
// register collision: b outputs to one of a's outputs (overwriting it)
|
||||||
if (b.regsOut & a.regsOut)
|
if (b.regsOut & a.regsOut)
|
||||||
return false;
|
return false;
|
||||||
|
if (b.crOut & a.crOut)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -451,12 +455,6 @@ void FindFunctions(const Core::CPUThreadGuard& guard, u32 startAddr, u32 endAddr
|
|||||||
unniceSize);
|
unniceSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 isCarryOp(const CodeOp& a)
|
static bool isCarryOp(const CodeOp& a)
|
||||||
{
|
{
|
||||||
return (a.opinfo->flags & FL_SET_CA) && !(a.opinfo->flags & FL_SET_OE) &&
|
return (a.opinfo->flags & FL_SET_CA) && !(a.opinfo->flags & FL_SET_OE) &&
|
||||||
@ -506,7 +504,7 @@ void PPCAnalyzer::ReorderInstructionsCore(u32 instructions, CodeOp* code, bool r
|
|||||||
// Reorder integer compares, rlwinm., and carry-affecting ops
|
// Reorder integer compares, rlwinm., and carry-affecting ops
|
||||||
// (if we add more merged branch instructions, add them here!)
|
// (if we add more merged branch instructions, add them here!)
|
||||||
if ((type == ReorderType::CROR && isCror(a)) || (type == ReorderType::Carry && isCarryOp(a)) ||
|
if ((type == ReorderType::CROR && isCror(a)) || (type == ReorderType::Carry && isCarryOp(a)) ||
|
||||||
(type == ReorderType::CMP && (isCmp(a) || a.crOut[0])))
|
(type == ReorderType::CMP && (type == ReorderType::CMP && a.crOut)))
|
||||||
{
|
{
|
||||||
// once we're next to a carry instruction, don't move away!
|
// once we're next to a carry instruction, don't move away!
|
||||||
if (type == ReorderType::Carry && i != start)
|
if (type == ReorderType::Carry && i != start)
|
||||||
|
@ -224,17 +224,17 @@ constexpr std::array<GekkoOPTemplate, 4> s_table4_3{{
|
|||||||
constexpr std::array<GekkoOPTemplate, 13> s_table19{{
|
constexpr std::array<GekkoOPTemplate, 13> s_table19{{
|
||||||
{528, "bcctrx", OpType::Branch, 1, FL_ENDBLOCK | FL_READ_CR_BI},
|
{528, "bcctrx", OpType::Branch, 1, FL_ENDBLOCK | FL_READ_CR_BI},
|
||||||
{16, "bclrx", OpType::Branch, 1, FL_ENDBLOCK | FL_READ_CR_BI},
|
{16, "bclrx", OpType::Branch, 1, FL_ENDBLOCK | FL_READ_CR_BI},
|
||||||
{257, "crand", OpType::CR, 1, FL_EVIL},
|
{257, "crand", OpType::CR, 1, 0},
|
||||||
{129, "crandc", OpType::CR, 1, FL_EVIL},
|
{129, "crandc", OpType::CR, 1, 0},
|
||||||
{289, "creqv", OpType::CR, 1, FL_EVIL},
|
{289, "creqv", OpType::CR, 1, 0},
|
||||||
{225, "crnand", OpType::CR, 1, FL_EVIL},
|
{225, "crnand", OpType::CR, 1, 0},
|
||||||
{33, "crnor", OpType::CR, 1, FL_EVIL},
|
{33, "crnor", OpType::CR, 1, 0},
|
||||||
{449, "cror", OpType::CR, 1, FL_EVIL},
|
{449, "cror", OpType::CR, 1, 0},
|
||||||
{417, "crorc", OpType::CR, 1, FL_EVIL},
|
{417, "crorc", OpType::CR, 1, 0},
|
||||||
{193, "crxor", OpType::CR, 1, FL_EVIL},
|
{193, "crxor", OpType::CR, 1, 0},
|
||||||
|
|
||||||
{150, "isync", OpType::InstructionCache, 1, FL_EVIL},
|
{150, "isync", OpType::InstructionCache, 1, FL_EVIL},
|
||||||
{0, "mcrf", OpType::System, 1, FL_EVIL | FL_SET_CRn | FL_READ_CRn},
|
{0, "mcrf", OpType::System, 1, FL_SET_CRn | FL_READ_CRn},
|
||||||
|
|
||||||
{50, "rfi", OpType::System, 2, FL_ENDBLOCK | FL_CHECKEXCEPTIONS | FL_PROGRAMEXCEPTION},
|
{50, "rfi", OpType::System, 2, FL_ENDBLOCK | FL_CHECKEXCEPTIONS | FL_PROGRAMEXCEPTION},
|
||||||
}};
|
}};
|
||||||
|
Reference in New Issue
Block a user