mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Look for downward jumps for elses when scanning.
Otherwise, we often end the function earlier than it should be.
This commit is contained in:
parent
43be44947f
commit
1bccfa4141
1 changed files with 63 additions and 5 deletions
|
@ -238,6 +238,57 @@ namespace MIPSAnalyst {
|
|||
}
|
||||
}
|
||||
|
||||
static u32 ScanAheadForJumpback(u32 fromAddr, u32 knownStart, u32 knownEnd) {
|
||||
static const u32 MAX_AHEAD_SCAN = 0x1000;
|
||||
|
||||
// Code might jump halfway up to before fromAddr, but after knownEnd.
|
||||
// In that area, there could be another jump up to the valid range.
|
||||
// So we track that for a second scan.
|
||||
u32 closestJumpbackAddr = INVALIDTARGET;
|
||||
u32 closestJumpbackTarget = fromAddr;
|
||||
|
||||
// We assume the furthest jumpback is within the func.
|
||||
u32 furthestJumpbackAddr = INVALIDTARGET;
|
||||
|
||||
for (u32 ahead = fromAddr; ahead < fromAddr + MAX_AHEAD_SCAN; ahead += 4) {
|
||||
MIPSOpcode aheadOp = Memory::Read_Instruction(ahead);
|
||||
u32 target = GetBranchTargetNoRA(ahead);
|
||||
if (target == INVALIDTARGET && ((aheadOp & 0xFC000000) == 0x08000000)) {
|
||||
target = GetJumpTarget(ahead);
|
||||
}
|
||||
|
||||
if (target != INVALIDTARGET) {
|
||||
// Only if it comes back up to known code within this func.
|
||||
if (target >= knownStart && target <= knownEnd) {
|
||||
furthestJumpbackAddr = ahead;
|
||||
}
|
||||
// But if it jumps above fromAddr, we should scan that area too...
|
||||
if (target < closestJumpbackTarget && target < fromAddr && target > knownEnd) {
|
||||
closestJumpbackAddr = ahead;
|
||||
closestJumpbackTarget = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closestJumpbackAddr != INVALIDTARGET && furthestJumpbackAddr == INVALIDTARGET) {
|
||||
for (u32 behind = closestJumpbackTarget; behind < fromAddr; behind += 4) {
|
||||
MIPSOpcode behindOp = Memory::Read_Instruction(behind);
|
||||
u32 target = GetBranchTargetNoRA(behind);
|
||||
if (target == INVALIDTARGET && ((behindOp & 0xFC000000) == 0x08000000)) {
|
||||
target = GetJumpTarget(behind);
|
||||
}
|
||||
|
||||
if (target != INVALIDTARGET) {
|
||||
if (target >= knownStart && target <= knownEnd) {
|
||||
furthestJumpbackAddr = closestJumpbackAddr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return furthestJumpbackAddr;
|
||||
}
|
||||
|
||||
void ScanForFunctions(u32 startAddr, u32 endAddr /*, std::vector<u32> knownEntries*/) {
|
||||
Function currentFunction = {startAddr};
|
||||
|
||||
|
@ -283,14 +334,21 @@ namespace MIPSAnalyst {
|
|||
if (looking) {
|
||||
if (addr >= furthestBranch) {
|
||||
u32 sureTarget = GetSureBranchTarget(addr);
|
||||
// Regular j only, jals are to new funcs.
|
||||
if (sureTarget == INVALIDTARGET && ((op & 0xFC000000) == 0x08000000)) {
|
||||
sureTarget = GetJumpTarget(addr);
|
||||
}
|
||||
|
||||
if (sureTarget != INVALIDTARGET && sureTarget < addr) {
|
||||
end = true;
|
||||
} else if (sureTarget != INVALIDTARGET) {
|
||||
// Okay, we have a downward jump. Might be an else or a tail call...
|
||||
// If there's a jump back upward in spitting distance of it, it's an else.
|
||||
u32 jumpback = ScanAheadForJumpback(sureTarget, currentFunction.start, furthestBranch);
|
||||
if (jumpback != INVALIDTARGET && jumpback > addr && jumpback > furthestBranch) {
|
||||
furthestBranch = jumpback;
|
||||
}
|
||||
}
|
||||
sureTarget = GetJumpTarget(addr);
|
||||
if (sureTarget != INVALIDTARGET && sureTarget < addr && ((op&0xFC000000)==0x08000000)) {
|
||||
end = true;
|
||||
}
|
||||
//end = true;
|
||||
}
|
||||
}
|
||||
if (end) {
|
||||
|
|
Loading…
Add table
Reference in a new issue