mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-09-27 09:05:28 -04:00
feat: analyzer resolve the complete constant-producing sequence with five-instruction backward scan stopped at LUI and therefore
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "ps2recomp/elf_analyzer.h"
|
||||
#include "ps2recomp/gif_dma_kick_analyzer.h"
|
||||
#include "ps2recomp/analysis_passes.h"
|
||||
#include "ps2recomp/elf_parser.h"
|
||||
#include "ps2recomp/r5900_decoder.h"
|
||||
@@ -358,9 +359,11 @@ namespace ps2recomp
|
||||
}
|
||||
|
||||
const auto &instructions = getDecodedInstructions(func);
|
||||
ConstantRegisterState constantRegisters;
|
||||
|
||||
for (const auto &inst : instructions)
|
||||
{
|
||||
const MemoryAccessHint directAddress = resolveMemoryAccessHint(inst, constantRegisters);
|
||||
if (inst.opcode == OPCODE_LW || inst.opcode == OPCODE_SW ||
|
||||
inst.opcode == OPCODE_LB || inst.opcode == OPCODE_SB ||
|
||||
inst.opcode == OPCODE_LH || inst.opcode == OPCODE_SH ||
|
||||
@@ -420,65 +423,46 @@ namespace ps2recomp
|
||||
}
|
||||
}
|
||||
}
|
||||
// Also check for direct addressing with LUI+ADDIU combinations
|
||||
else if (inst.opcode == OPCODE_LW || inst.opcode == OPCODE_SW)
|
||||
|
||||
else if ((inst.opcode == OPCODE_LW || inst.opcode == OPCODE_SW) && directAddress.hasAddress)
|
||||
{
|
||||
// Look for the LUI instruction that sets up the high bits
|
||||
uint32_t baseAddr = 0;
|
||||
for (int i = 1; i <= 5 && static_cast<int>(inst.address) - i * 4 >= static_cast<int>(func.start); i++)
|
||||
{
|
||||
uint32_t prevAddr = inst.address - i * 4;
|
||||
uint32_t prevInst = 0;
|
||||
if (!tryReadWord(m_elfParser.get(), prevAddr, prevInst))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const uint32_t targetAddr = directAddress.address;
|
||||
|
||||
// Check if it's a LUI instruction for the same register
|
||||
if (OPCODE(prevInst) == OPCODE_LUI && RT(prevInst) == inst.rs)
|
||||
{
|
||||
baseAddr = IMMEDIATE(prevInst) << 16;
|
||||
break;
|
||||
}
|
||||
// Detect MMIO accesses
|
||||
if (
|
||||
(targetAddr >= 0x10000000 && targetAddr < 0x14000000) || // I/O
|
||||
(targetAddr >= 0x70000000 && targetAddr < 0x70004000) // Scratchpad
|
||||
)
|
||||
{
|
||||
m_mmioByInstructionAddress[inst.address] = targetAddr;
|
||||
std::cout << "Detected MMIO access at " << std::hex << inst.address << " -> " << targetAddr << std::dec << std::endl;
|
||||
}
|
||||
|
||||
if (baseAddr != 0)
|
||||
for (const auto §ion : m_context.sections)
|
||||
{
|
||||
uint32_t targetAddr = baseAddr + static_cast<int16_t>(inst.immediate);
|
||||
|
||||
// Detect MMIO accesses
|
||||
if ((targetAddr >= 0x10000000 && targetAddr < 0x14000000) || // I/O
|
||||
(targetAddr >= 0x70000000 && targetAddr < 0x70004000)) // Scratchpad
|
||||
if (targetAddr >= section.address && targetAddr < section.address + section.size)
|
||||
{
|
||||
m_mmioByInstructionAddress[inst.address] = targetAddr;
|
||||
std::cout << "Detected MMIO access at " << std::hex << inst.address
|
||||
<< " -> " << targetAddr << std::dec << std::endl;
|
||||
}
|
||||
auto symIt = std::find_if(m_context.symbols.begin(), m_context.symbols.end(),
|
||||
[targetAddr](const Symbol &s)
|
||||
{ return !s.isFunction && s.address <= targetAddr &&
|
||||
s.address + s.size > targetAddr; });
|
||||
|
||||
for (const auto §ion : m_context.sections)
|
||||
{
|
||||
if (targetAddr >= section.address && targetAddr < section.address + section.size)
|
||||
if (symIt != m_context.symbols.end())
|
||||
{
|
||||
auto symIt = std::find_if(m_context.symbols.begin(), m_context.symbols.end(),
|
||||
[targetAddr](const Symbol &s)
|
||||
{ return !s.isFunction && s.address <= targetAddr &&
|
||||
s.address + s.size > targetAddr; });
|
||||
std::cout << "Function " << func.name << " directly accesses "
|
||||
<< (inst.opcode == OPCODE_LW ? "reads from" : "writes to")
|
||||
<< " data symbol " << symIt->name
|
||||
<< " at 0x" << std::hex << targetAddr << std::dec << std::endl;
|
||||
|
||||
if (symIt != m_context.symbols.end())
|
||||
{
|
||||
std::cout << "Function " << func.name << " directly accesses "
|
||||
<< (inst.opcode == OPCODE_LW ? "reads from" : "writes to")
|
||||
<< " data symbol " << symIt->name
|
||||
<< " at 0x" << std::hex << targetAddr << std::dec << std::endl;
|
||||
|
||||
m_functionDataUsage[func.name].insert(symIt->name);
|
||||
}
|
||||
break;
|
||||
m_functionDataUsage[func.name].insert(symIt->name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateConstantRegisters(inst, constantRegisters);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user