Merge pull request #6910 from lioncash/analyst
PPCAnalyst: Clean up indexing expressions in Analyze()
This commit is contained in:
commit
9387b7dd32
|
@ -833,39 +833,41 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, std:
|
||||||
BitSet32 fprInUse, gprInUse, gprInReg, fprInXmm;
|
BitSet32 fprInUse, gprInUse, gprInReg, fprInXmm;
|
||||||
for (int i = block->m_num_instructions - 1; i >= 0; i--)
|
for (int i = block->m_num_instructions - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
bool opWantsCR0 = code[i].wantsCR0;
|
CodeOp& op = code[i];
|
||||||
bool opWantsCR1 = code[i].wantsCR1;
|
|
||||||
bool opWantsFPRF = code[i].wantsFPRF;
|
const bool opWantsCR0 = op.wantsCR0;
|
||||||
bool opWantsCA = code[i].wantsCA;
|
const bool opWantsCR1 = op.wantsCR1;
|
||||||
code[i].wantsCR0 = wantsCR0 || code[i].canEndBlock;
|
const bool opWantsFPRF = op.wantsFPRF;
|
||||||
code[i].wantsCR1 = wantsCR1 || code[i].canEndBlock;
|
const bool opWantsCA = op.wantsCA;
|
||||||
code[i].wantsFPRF = wantsFPRF || code[i].canEndBlock;
|
op.wantsCR0 = wantsCR0 || op.canEndBlock;
|
||||||
code[i].wantsCA = wantsCA || code[i].canEndBlock;
|
op.wantsCR1 = wantsCR1 || op.canEndBlock;
|
||||||
wantsCR0 |= opWantsCR0 || code[i].canEndBlock;
|
op.wantsFPRF = wantsFPRF || op.canEndBlock;
|
||||||
wantsCR1 |= opWantsCR1 || code[i].canEndBlock;
|
op.wantsCA = wantsCA || op.canEndBlock;
|
||||||
wantsFPRF |= opWantsFPRF || code[i].canEndBlock;
|
wantsCR0 |= opWantsCR0 || op.canEndBlock;
|
||||||
wantsCA |= opWantsCA || code[i].canEndBlock;
|
wantsCR1 |= opWantsCR1 || op.canEndBlock;
|
||||||
wantsCR0 &= !code[i].outputCR0 || opWantsCR0;
|
wantsFPRF |= opWantsFPRF || op.canEndBlock;
|
||||||
wantsCR1 &= !code[i].outputCR1 || opWantsCR1;
|
wantsCA |= opWantsCA || op.canEndBlock;
|
||||||
wantsFPRF &= !code[i].outputFPRF || opWantsFPRF;
|
wantsCR0 &= !op.outputCR0 || opWantsCR0;
|
||||||
wantsCA &= !code[i].outputCA || opWantsCA;
|
wantsCR1 &= !op.outputCR1 || opWantsCR1;
|
||||||
code[i].gprInUse = gprInUse;
|
wantsFPRF &= !op.outputFPRF || opWantsFPRF;
|
||||||
code[i].fprInUse = fprInUse;
|
wantsCA &= !op.outputCA || opWantsCA;
|
||||||
code[i].gprInReg = gprInReg;
|
op.gprInUse = gprInUse;
|
||||||
code[i].fprInXmm = fprInXmm;
|
op.fprInUse = fprInUse;
|
||||||
|
op.gprInReg = gprInReg;
|
||||||
|
op.fprInXmm = fprInXmm;
|
||||||
// TODO: if there's no possible endblocks or exceptions in between, tell the regcache
|
// TODO: if there's no possible endblocks or exceptions in between, tell the regcache
|
||||||
// we can throw away a register if it's going to be overwritten later.
|
// we can throw away a register if it's going to be overwritten later.
|
||||||
gprInUse |= code[i].regsIn;
|
gprInUse |= op.regsIn;
|
||||||
gprInReg |= code[i].regsIn;
|
gprInReg |= op.regsIn;
|
||||||
fprInUse |= code[i].fregsIn;
|
fprInUse |= op.fregsIn;
|
||||||
if (strncmp(code[i].opinfo->opname, "stfd", 4))
|
if (strncmp(op.opinfo->opname, "stfd", 4))
|
||||||
fprInXmm |= code[i].fregsIn;
|
fprInXmm |= op.fregsIn;
|
||||||
// For now, we need to count output registers as "used" though; otherwise the flush
|
// For now, we need to count output registers as "used" though; otherwise the flush
|
||||||
// will result in a redundant store (e.g. store to regcache, then store again to
|
// will result in a redundant store (e.g. store to regcache, then store again to
|
||||||
// the same location later).
|
// the same location later).
|
||||||
gprInUse |= code[i].regsOut;
|
gprInUse |= op.regsOut;
|
||||||
if (code[i].fregOut >= 0)
|
if (op.fregOut >= 0)
|
||||||
fprInUse[code[i].fregOut] = true;
|
fprInUse[op.fregOut] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward scan, for flags that need the other direction for calculation.
|
// Forward scan, for flags that need the other direction for calculation.
|
||||||
|
@ -873,55 +875,57 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, std:
|
||||||
BitSet8 gqrUsed, gqrModified;
|
BitSet8 gqrUsed, gqrModified;
|
||||||
for (u32 i = 0; i < block->m_num_instructions; i++)
|
for (u32 i = 0; i < block->m_num_instructions; i++)
|
||||||
{
|
{
|
||||||
gprBlockInputs |= code[i].regsIn & ~gprDefined;
|
CodeOp& op = code[i];
|
||||||
gprDefined |= code[i].regsOut;
|
|
||||||
|
|
||||||
code[i].fprIsSingle = fprIsSingle;
|
gprBlockInputs |= op.regsIn & ~gprDefined;
|
||||||
code[i].fprIsDuplicated = fprIsDuplicated;
|
gprDefined |= op.regsOut;
|
||||||
code[i].fprIsStoreSafe = fprIsStoreSafe;
|
|
||||||
if (code[i].fregOut >= 0)
|
op.fprIsSingle = fprIsSingle;
|
||||||
|
op.fprIsDuplicated = fprIsDuplicated;
|
||||||
|
op.fprIsStoreSafe = fprIsStoreSafe;
|
||||||
|
if (op.fregOut >= 0)
|
||||||
{
|
{
|
||||||
fprIsSingle[code[i].fregOut] = false;
|
fprIsSingle[op.fregOut] = false;
|
||||||
fprIsDuplicated[code[i].fregOut] = false;
|
fprIsDuplicated[op.fregOut] = false;
|
||||||
fprIsStoreSafe[code[i].fregOut] = false;
|
fprIsStoreSafe[op.fregOut] = false;
|
||||||
// Single, duplicated, and doesn't need PPC_FP.
|
// Single, duplicated, and doesn't need PPC_FP.
|
||||||
if (code[i].opinfo->type == OpType::SingleFP)
|
if (op.opinfo->type == OpType::SingleFP)
|
||||||
{
|
{
|
||||||
fprIsSingle[code[i].fregOut] = true;
|
fprIsSingle[op.fregOut] = true;
|
||||||
fprIsDuplicated[code[i].fregOut] = true;
|
fprIsDuplicated[op.fregOut] = true;
|
||||||
fprIsStoreSafe[code[i].fregOut] = true;
|
fprIsStoreSafe[op.fregOut] = true;
|
||||||
}
|
}
|
||||||
// Single and duplicated, but might be a denormal (not safe to skip PPC_FP).
|
// Single and duplicated, but might be a denormal (not safe to skip PPC_FP).
|
||||||
// TODO: if we go directly from a load to store, skip conversion entirely?
|
// TODO: if we go directly from a load to store, skip conversion entirely?
|
||||||
// TODO: if we go directly from a load to a float instruction, and the value isn't used
|
// TODO: if we go directly from a load to a float instruction, and the value isn't used
|
||||||
// for anything else, we can skip PPC_FP on a load too.
|
// for anything else, we can skip PPC_FP on a load too.
|
||||||
if (!strncmp(code[i].opinfo->opname, "lfs", 3))
|
if (!strncmp(op.opinfo->opname, "lfs", 3))
|
||||||
{
|
{
|
||||||
fprIsSingle[code[i].fregOut] = true;
|
fprIsSingle[op.fregOut] = true;
|
||||||
fprIsDuplicated[code[i].fregOut] = true;
|
fprIsDuplicated[op.fregOut] = true;
|
||||||
}
|
}
|
||||||
// Paired are still floats, but the top/bottom halves may differ.
|
// Paired are still floats, but the top/bottom halves may differ.
|
||||||
if (code[i].opinfo->type == OpType::PS || code[i].opinfo->type == OpType::LoadPS)
|
if (op.opinfo->type == OpType::PS || op.opinfo->type == OpType::LoadPS)
|
||||||
{
|
{
|
||||||
fprIsSingle[code[i].fregOut] = true;
|
fprIsSingle[op.fregOut] = true;
|
||||||
fprIsStoreSafe[code[i].fregOut] = true;
|
fprIsStoreSafe[op.fregOut] = true;
|
||||||
}
|
}
|
||||||
// Careful: changing the float mode in a block breaks this optimization, since
|
// Careful: changing the float mode in a block breaks this optimization, since
|
||||||
// a previous float op might have had had FTZ off while the later store has FTZ
|
// a previous float op might have had had FTZ off while the later store has FTZ
|
||||||
// on. So, discard all information we have.
|
// on. So, discard all information we have.
|
||||||
if (!strncmp(code[i].opinfo->opname, "mtfs", 4))
|
if (!strncmp(op.opinfo->opname, "mtfs", 4))
|
||||||
fprIsStoreSafe = BitSet32(0);
|
fprIsStoreSafe = BitSet32(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code[i].opinfo->type == OpType::StorePS || code[i].opinfo->type == OpType::LoadPS)
|
if (op.opinfo->type == OpType::StorePS || op.opinfo->type == OpType::LoadPS)
|
||||||
{
|
{
|
||||||
int gqr = code[i].inst.OPCD == 4 ? code[i].inst.Ix : code[i].inst.I;
|
const int gqr = op.inst.OPCD == 4 ? op.inst.Ix : op.inst.I;
|
||||||
gqrUsed[gqr] = true;
|
gqrUsed[gqr] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code[i].inst.OPCD == 31 && code[i].inst.SUBOP10 == 467) // mtspr
|
if (op.inst.OPCD == 31 && op.inst.SUBOP10 == 467) // mtspr
|
||||||
{
|
{
|
||||||
int gqr = ((code[i].inst.SPRU << 5) | code[i].inst.SPRL) - SPR_GQR0;
|
const int gqr = ((op.inst.SPRU << 5) | op.inst.SPRL) - SPR_GQR0;
|
||||||
if (gqr >= 0 && gqr <= 7)
|
if (gqr >= 0 && gqr <= 7)
|
||||||
gqrModified[gqr] = true;
|
gqrModified[gqr] = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue