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; return false;
} }
uint32 target = m_context.m_pArch->GetInstructionEffectiveAddress(&m_context, branchInstAddr, inst); uint32 target = m_context.m_pArch->GetInstructionEffectiveAddress(&m_context, branchInstAddr, inst);
if(target == MIPS_INVALID_PC)
{
return false;
}
return target == m_begin; 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; branchAddress &= m_addressMask;
const auto linkSlot = LINK_SLOT_BRANCH; const auto linkSlot = LINK_SLOT_BRANCH;
@ -210,7 +210,7 @@ protected:
virtual void PartitionFunction(uint32 startAddress) virtual void PartitionFunction(uint32 startAddress)
{ {
uint32 endAddress = startAddress + MAX_BLOCK_SIZE; uint32 endAddress = startAddress + MAX_BLOCK_SIZE;
uint32 branchAddress = 0; uint32 branchAddress = MIPS_INVALID_PC;
for(uint32 address = startAddress; address < endAddress; address += 4) for(uint32 address = startAddress; address < endAddress; address += 4)
{ {
uint32 opcode = m_context.m_pMemoryMap->GetInstruction(address); 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 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; if(branchType != MIPS_BRANCH_NORMAL) continue;
uint32 branchTarget = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, address, opcode); 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 //Check if pointing inside our subroutine. If so, don't bother
if(branchTarget >= subroutine.start && branchTarget <= subroutine.end) continue; if(branchTarget >= subroutine.start && branchTarget <= subroutine.end) continue;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -186,11 +186,14 @@ void CDisAsmWnd::ShowContextMenu(const QPoint& pos)
{ {
char sTemp[256]; char sTemp[256];
uint32 nAddress = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, m_selected, nOpcode); uint32 nAddress = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, m_selected, nOpcode);
snprintf(sTemp, countof(sTemp), ("Go to 0x%08X"), nAddress); if(nAddress != MIPS_INVALID_PC)
QAction* goToEaAction = new QAction(this); {
goToEaAction->setText(sTemp); snprintf(sTemp, countof(sTemp), ("Go to 0x%08X"), nAddress);
connect(goToEaAction, &QAction::triggered, std::bind(&CDisAsmWnd::GotoEA, this)); QAction* goToEaAction = new QAction(this);
rightClickMenu->addAction(goToEaAction); goToEaAction->setText(sTemp);
connect(goToEaAction, &QAction::triggered, std::bind(&CDisAsmWnd::GotoEA, this));
rightClickMenu->addAction(goToEaAction);
}
} }
} }
} }
@ -368,6 +371,7 @@ void CDisAsmWnd::GotoEA()
if(m_ctx->m_pArch->IsInstructionBranch(m_ctx, m_selected, nOpcode) == MIPS_BRANCH_NORMAL) 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); uint32 nAddress = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, m_selected, nOpcode);
assert(nAddress != MIPS_INVALID_PC);
if(m_address != nAddress) 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 opcode = context->m_pMemoryMap->GetInstruction(i);
uint32 ea = context->m_pArch->GetInstructionEffectiveAddress(context, i, opcode); uint32 ea = context->m_pArch->GetInstructionEffectiveAddress(context, i, opcode);
if(ea == MIPS_INVALID_PC) continue;
if(ea == address) if(ea == address)
{ {
callers.push_back(i); callers.push_back(i);

View file

@ -312,12 +312,15 @@ std::string CQtDisAsmTableModel::GetInstructionMetadata(uint32 address) const
if(m_ctx->m_pArch->IsInstructionBranch(m_ctx, address, opcode) == MIPS_BRANCH_NORMAL) if(m_ctx->m_pArch->IsInstructionBranch(m_ctx, address, opcode) == MIPS_BRANCH_NORMAL)
{ {
uint32 effAddr = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, address, opcode); uint32 effAddr = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, address, opcode);
const char* tag = m_ctx->m_Functions.Find(effAddr); if(effAddr != MIPS_INVALID_PC)
if(tag != nullptr)
{ {
disAsm += ("-> "); const char* tag = m_ctx->m_Functions.Find(effAddr);
disAsm += tag; if(tag != nullptr)
commentDrawn = true; {
disAsm += ("-> ");
disAsm += tag;
commentDrawn = true;
}
} }
} }
} }