summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorSepalani <sepalani@hotmail.fr>2017-05-07 03:39:39 +0100
committerSepalani <sepalani@hotmail.fr>2017-05-07 04:55:36 +0100
commit95d0a48759f844efbf136fb3bc40db2ae20b08d9 (patch)
tree22198bf0004e5c92ee9e15a25f641ccdb6d1561f /Source/Core
parentef4a1f0ec7dd574a58d4737c112fc2584cd2a7fe (diff)
PPCAnalyst: EvaluateBranchTarget improved
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/PPCAnalyst.cpp71
1 files changed, 35 insertions, 36 deletions
diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp
index 041c196e11..6b8b23d4ec 100644
--- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp
+++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp
@@ -53,7 +53,15 @@ static u32 EvaluateBranchTarget(UGeckoInstruction instr, u32 pc)
{
switch (instr.OPCD)
{
- case 18: // branch instruction
+ case 16: // bcx - Branch Conditional instructions
+ {
+ u32 target = SignExt16(instr.BD << 2);
+ if (!instr.AA)
+ target += pc;
+
+ return target;
+ }
+ case 18: // bx - Branch instructions
{
u32 target = SignExt26(instr.LI << 2);
if (!instr.AA)
@@ -83,11 +91,10 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
func.callers.clear();
func.size = 0;
func.flags = FFLAG_LEAF;
- u32 addr = startAddr;
u32 farthestInternalBranchTarget = startAddr;
int numInternalBranches = 0;
- while (true)
+ for (u32 addr = startAddr; true; addr += 4)
{
func.size += 4;
if (func.size >= CODEBUFFER_SIZE * 4 || !PowerPC::HostIsRAMAddress(addr)) // weird
@@ -110,22 +117,19 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
// 4e800021 is blrl, not the end of a function
if (instr.hex == 0x4e800020 || instr.hex == 0x4C000064)
{
+ // Not this one, continue..
if (farthestInternalBranchTarget > addr)
- {
- // bah, not this one, continue..
- }
- else
- {
- // a final blr!
- // We're done! Looks like we have a neat valid function. Perfect.
- // Let's calc the checksum and get outta here
- func.address = startAddr;
- func.analyzed = true;
- func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr);
- if (numInternalBranches == 0)
- func.flags |= FFLAG_STRAIGHT;
- return true;
- }
+ continue;
+
+ // A final blr!
+ // We're done! Looks like we have a neat valid function. Perfect.
+ // Let's calc the checksum and get outta here
+ func.address = startAddr;
+ func.analyzed = true;
+ func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr);
+ if (numInternalBranches == 0)
+ func.flags |= FFLAG_STRAIGHT;
+ return true;
}
/*
else if ((instr.hex & 0xFC000000) == (0x4b000000 & 0xFC000000) && !instr.LK)
@@ -155,28 +159,24 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
}
else
{
- if (instr.OPCD == 16)
- {
- u32 target = SignExt16(instr.BD << 2);
+ u32 target = EvaluateBranchTarget(instr, addr);
+ if (target == INVALID_BRANCH_TARGET)
+ continue;
- if (!instr.AA)
- target += addr;
-
- if (target > farthestInternalBranchTarget && !instr.LK)
- {
- farthestInternalBranchTarget = target;
- }
- numInternalBranches++;
+ if (instr.LK)
+ {
+ // Found a branch-n-link
+ func.calls.emplace_back(target, addr);
+ func.flags &= ~FFLAG_LEAF;
}
- else
+ else if (instr.OPCD == 16)
{
- u32 target = EvaluateBranchTarget(instr, addr);
- if (target != INVALID_BRANCH_TARGET && instr.LK)
+ // Found a conditional branch
+ if (target > farthestInternalBranchTarget)
{
- // we found a branch-n-link!
- func.calls.emplace_back(target, addr);
- func.flags &= ~FFLAG_LEAF;
+ farthestInternalBranchTarget = target;
}
+ numInternalBranches++;
}
}
}
@@ -184,7 +184,6 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
{
return false;
}
- addr += 4;
}
}