Add proper "empty" return value to GetEffectiveAddress.

Zero is valid and cannot be used as "empty".
This commit is contained in:
Jean-Philip Desjardins 2022-12-07 14:48:20 -05:00
parent e283a2fc79
commit 38d3775a07
13 changed files with 35 additions and 23 deletions

View file

@ -206,6 +206,10 @@ void CBasicBlock::CompileRange(CMipsJitter* jitter)
return false;
}
uint32 target = m_context.m_pArch->GetInstructionEffectiveAddress(&m_context, branchInstAddr, inst);
if(target == MIPS_INVALID_PC)
{
return false;
}
return target == m_begin;
}();

View file

@ -172,7 +172,7 @@ protected:
}
}
if((branchAddress != 0) && block->HasLinkSlot(LINK_SLOT_BRANCH))
if((branchAddress != MIPS_INVALID_PC) && block->HasLinkSlot(LINK_SLOT_BRANCH))
{
branchAddress &= m_addressMask;
const auto linkSlot = LINK_SLOT_BRANCH;
@ -210,7 +210,7 @@ protected:
virtual void PartitionFunction(uint32 startAddress)
{
uint32 endAddress = startAddress + MAX_BLOCK_SIZE;
uint32 branchAddress = 0;
uint32 branchAddress = MIPS_INVALID_PC;
for(uint32 address = startAddress; address < endAddress; address += 4)
{
uint32 opcode = m_context.m_pMemoryMap->GetInstruction(address);

View file

@ -230,7 +230,7 @@ uint32 CMA_MIPSIV::ReflCOPEffeAddr(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAdd
}
else
{
return 0;
return MIPS_INVALID_PC;
}
}

View file

@ -269,6 +269,7 @@ void CMIPSAnalysis::ExpandSubroutines(uint32 executableStart, uint32 executableE
if(branchType != MIPS_BRANCH_NORMAL) continue;
uint32 branchTarget = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, address, opcode);
if(branchTarget == MIPS_INVALID_PC) continue;
//Check if pointing inside our subroutine. If so, don't bother
if(branchTarget >= subroutine.start && branchTarget <= subroutine.end) continue;

View file

@ -1,7 +1,6 @@
#include "MIPSReflection.h"
#include <string.h>
class CMIPS;
#include "MIPS.h"
using namespace MIPSReflection;
@ -64,7 +63,7 @@ uint32 MIPSReflection::SubTableEffAddr(INSTRUCTION* pInstr, CMIPS* pCtx, uint32
pInstr = DereferenceInstruction(pInstr->pSubTable, nOpcode);
if(pInstr->pGetEffectiveAddress == NULL)
{
return 0;
return MIPS_INVALID_PC;
}
return pInstr->pGetEffectiveAddress(pInstr, pCtx, nAddress, nOpcode);
}

View file

@ -40,6 +40,7 @@ bool CEeBasicBlock::IsIdleLoopBlock() const
//Check that the branch target is ourself
uint32 branchTarget = m_context.m_pArch->GetInstructionEffectiveAddress(&m_context, endInstructionAddress, endInstruction);
if(branchTarget == MIPS_INVALID_PC) return false;
if(branchTarget != m_begin) return false;
uint32 compareRs = 0;

View file

@ -1349,12 +1349,12 @@ uint32 CMA_VU::CLower::GetInstructionEffectiveAddress(CMIPS* context, uint32 add
{
if(IsLOI(context, address))
{
return 0;
return MIPS_INVALID_PC;
}
if(opcode == OPCODE_NOP)
{
return 0;
return MIPS_INVALID_PC;
}
INSTRUCTION instr;

View file

@ -105,7 +105,7 @@ void CVuAnalysis::Analyse(CMIPS* ctx, uint32 begin, uint32 end)
if(branchType == MIPS_BRANCH_NORMAL)
{
uint32 branchTarget = ctx->m_pArch->GetInstructionEffectiveAddress(ctx, address, lowerInstruction);
if(branchTarget != 0)
if(branchTarget != MIPS_INVALID_PC)
{
auto subroutine = ctx->m_analysis->FindSubroutine(branchTarget);
if(subroutine)

View file

@ -230,9 +230,7 @@ void CVuBasicBlock::CompileRange(CMipsJitter* jitter)
return false;
}
uint32 target = m_context.m_pArch->GetInstructionEffectiveAddress(&m_context, branchInstAddr, inst);
//TODO: GetInstructionEffectiveAddress should return something else when the EA can't be computed
//statically as 0 is a valid address. There's some other implications to this though.
if(target == 0)
if(target == MIPS_INVALID_PC)
{
return false;
}
@ -321,6 +319,7 @@ bool CVuBasicBlock::CheckIsSpecialIntegerLoop(unsigned int regI) const
{
assert(IsConditionalBranch(opcodeLo));
uint32 branchTarget = arch->GetInstructionEffectiveAddress(&m_context, address, opcodeLo);
if(branchTarget == MIPS_INVALID_PC) return false;
if(branchTarget != m_begin) return false;
}
else

View file

@ -70,7 +70,7 @@ BasicBlockPtr CVuExecutor::BlockFactory(CMIPS& context, uint32 begin, uint32 end
void CVuExecutor::PartitionFunction(uint32 startAddress)
{
uint32 endAddress = startAddress + MAX_BLOCK_SIZE - 4;
uint32 branchAddress = 0;
uint32 branchAddress = MIPS_INVALID_PC;
for(uint32 address = startAddress; address < endAddress; address += 8)
{
uint32 addrLo = address + 0;

View file

@ -186,6 +186,8 @@ void CDisAsmWnd::ShowContextMenu(const QPoint& pos)
{
char sTemp[256];
uint32 nAddress = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, m_selected, nOpcode);
if(nAddress != MIPS_INVALID_PC)
{
snprintf(sTemp, countof(sTemp), ("Go to 0x%08X"), nAddress);
QAction* goToEaAction = new QAction(this);
goToEaAction->setText(sTemp);
@ -194,6 +196,7 @@ void CDisAsmWnd::ShowContextMenu(const QPoint& pos)
}
}
}
}
if(HistoryHasPrevious())
{
@ -368,6 +371,7 @@ void CDisAsmWnd::GotoEA()
if(m_ctx->m_pArch->IsInstructionBranch(m_ctx, m_selected, nOpcode) == MIPS_BRANCH_NORMAL)
{
uint32 nAddress = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, m_selected, nOpcode);
assert(nAddress != MIPS_INVALID_PC);
if(m_address != nAddress)
{

View file

@ -632,6 +632,7 @@ std::vector<uint32> QtDebugger::FindCallers(CMIPS* context, uint32 address)
{
uint32 opcode = context->m_pMemoryMap->GetInstruction(i);
uint32 ea = context->m_pArch->GetInstructionEffectiveAddress(context, i, opcode);
if(ea == MIPS_INVALID_PC) continue;
if(ea == address)
{
callers.push_back(i);

View file

@ -312,6 +312,8 @@ std::string CQtDisAsmTableModel::GetInstructionMetadata(uint32 address) const
if(m_ctx->m_pArch->IsInstructionBranch(m_ctx, address, opcode) == MIPS_BRANCH_NORMAL)
{
uint32 effAddr = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, address, opcode);
if(effAddr != MIPS_INVALID_PC)
{
const char* tag = m_ctx->m_Functions.Find(effAddr);
if(tag != nullptr)
{
@ -321,6 +323,7 @@ std::string CQtDisAsmTableModel::GetInstructionMetadata(uint32 address) const
}
}
}
}
return disAsm.c_str();
}