mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-06-06 18:31:03 +00:00
bctr and conditional returns
This commit is contained in:
parent
cbc28c6451
commit
27f6604072
@ -18,9 +18,19 @@ size_t Function::SearchBlock(size_t address) const
|
|||||||
const auto begin = base + block.base;
|
const auto begin = base + block.base;
|
||||||
const auto end = begin + block.size;
|
const auto end = begin + block.size;
|
||||||
|
|
||||||
if (address >= begin && address < end)
|
if (begin != end)
|
||||||
{
|
{
|
||||||
return i;
|
if (address >= begin && address < end)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // fresh block
|
||||||
|
{
|
||||||
|
if (address == begin)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +63,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto& curBlock = blocks[blockStack.back()];
|
auto& curBlock = blocks[blockStack.back()];
|
||||||
|
DEBUG(const auto blockBase = curBlock.base);
|
||||||
const auto instruction = std::byteswap(*data);
|
const auto instruction = std::byteswap(*data);
|
||||||
|
|
||||||
const auto op = PPC_OP(instruction);
|
const auto op = PPC_OP(instruction);
|
||||||
@ -98,7 +109,6 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
|
|||||||
|
|
||||||
if (lBlock == -1)
|
if (lBlock == -1)
|
||||||
{
|
{
|
||||||
DEBUG(const auto blockBase = curBlock.base);
|
|
||||||
blocks.emplace_back(lBase, 0).projectedSize = rBase - lBase;
|
blocks.emplace_back(lBase, 0).projectedSize = rBase - lBase;
|
||||||
lBlock = blocks.size() - 1;
|
lBlock = blocks.size() - 1;
|
||||||
|
|
||||||
@ -110,7 +120,6 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
|
|||||||
auto rBlock = fn.SearchBlock(base + rBase);
|
auto rBlock = fn.SearchBlock(base + rBase);
|
||||||
if (rBlock == -1)
|
if (rBlock == -1)
|
||||||
{
|
{
|
||||||
DEBUG(const auto blockBase = curBlock.base);
|
|
||||||
blocks.emplace_back(branchDest - base, 0);
|
blocks.emplace_back(branchDest - base, 0);
|
||||||
rBlock = blocks.size() - 1;
|
rBlock = blocks.size() - 1;
|
||||||
|
|
||||||
@ -120,7 +129,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
|
|||||||
|
|
||||||
RESTORE_DATA();
|
RESTORE_DATA();
|
||||||
}
|
}
|
||||||
else if (op == PPC_OP_B || instruction == 0 || (insn.opcode != nullptr && insn.opcode->id == PPC_INST_BLR)) // b, blr, end padding
|
else if (op == PPC_OP_B || instruction == 0 || (op == PPC_OP_CTR && (xop == 16 || xop == 528))) // b, blr, end padding
|
||||||
{
|
{
|
||||||
if (!isLink)
|
if (!isLink)
|
||||||
{
|
{
|
||||||
@ -135,7 +144,6 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep analyzing if we have continuity
|
|
||||||
assert(!PPC_BA(instruction));
|
assert(!PPC_BA(instruction));
|
||||||
const auto branchDest = addr + PPC_BI(instruction);
|
const auto branchDest = addr + PPC_BI(instruction);
|
||||||
|
|
||||||
@ -160,15 +168,36 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
|
|||||||
|
|
||||||
if (branchBlock == -1)
|
if (branchBlock == -1)
|
||||||
{
|
{
|
||||||
DEBUG(const auto blockBase = curBlock.base);
|
|
||||||
blocks.emplace_back(branchBase, 0, sizeProjection);
|
blocks.emplace_back(branchBase, 0, sizeProjection);
|
||||||
|
|
||||||
blockStack.emplace_back(blocks.size() - 1);
|
blockStack.emplace_back(blocks.size() - 1);
|
||||||
|
|
||||||
DEBUG(blocks.back().parent = blockBase);
|
DEBUG(blocks.back().parent = blockBase);
|
||||||
RESTORE_DATA();
|
RESTORE_DATA();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (op == PPC_OP_CTR)
|
||||||
|
{
|
||||||
|
// 5th bit of BO tells cpu to ignore the counter, which is a blr/bctr otherwise it's conditional
|
||||||
|
const auto conditional = !(PPC_BO(instruction) & 0x10);
|
||||||
|
if (conditional)
|
||||||
|
{
|
||||||
|
// right block's just going to return
|
||||||
|
const auto lBase = (addr - base) + 4;
|
||||||
|
auto lBlock = fn.SearchBlock(lBase);
|
||||||
|
if (lBlock == -1)
|
||||||
|
{
|
||||||
|
blocks.emplace_back(lBase, 0);
|
||||||
|
lBlock = blocks.size() - 1;
|
||||||
|
|
||||||
|
DEBUG(blocks[lBlock].parent = blockBase);
|
||||||
|
blockStack.emplace_back(lBlock);
|
||||||
|
RESTORE_DATA();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RESTORE_DATA();
|
RESTORE_DATA();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user