- Improved call stack.

This commit is contained in:
DH 2013-11-23 17:20:31 +02:00
parent cbe4ab253c
commit 8463694d4f
3 changed files with 46 additions and 10 deletions

View file

@ -145,7 +145,7 @@ void CPUThread::NextPc(u8 instr_size)
}
}
void CPUThread::SetBranch(const u64 pc)
void CPUThread::SetBranch(const u64 pc, bool record_branch)
{
if(!Memory.IsGoodAddr(m_offset + pc))
{
@ -155,6 +155,9 @@ void CPUThread::SetBranch(const u64 pc)
m_is_branch = true;
nPC = pc;
if(record_branch)
CallStackBranch(pc);
}
void CPUThread::SetPc(const u64 pc)

View file

@ -132,7 +132,7 @@ public:
int ThreadStatus();
void NextPc(u8 instr_size);
void SetBranch(const u64 pc);
void SetBranch(const u64 pc, bool record_branch = false);
void SetPc(const u64 pc);
void SetEntry(const u64 entry);
@ -171,15 +171,50 @@ public:
virtual void Exec();
void ExecOnce();
Stack<u64> m_call_stack;
struct CallStackItem
{
u64 pc;
u64 branch_pc;
};
Stack<CallStackItem> m_call_stack;
wxString CallStackToString()
{
wxString ret = "Call Stack:\n==========\n";
for(uint i=0; i<m_call_stack.GetCount(); ++i)
ret += wxString::Format("0x%llx\n", m_call_stack.Get(i));
{
ret += wxString::Format("0x%llx -> 0x%llx\n", m_call_stack[i].pc, m_call_stack[i].branch_pc);
}
return ret;
}
void CallStackBranch(u64 pc)
{
for(int i=m_call_stack.GetCount() - 1; i >= 0; --i)
{
if(CallStackGetNextPC(m_call_stack[i].pc) == pc)
{
m_call_stack.RemoveAt(i, m_call_stack.GetCount() - i);
return;
}
}
CallStackItem new_item;
new_item.branch_pc = pc;
new_item.pc = PC;
m_call_stack.AddCpy(new_item);
}
virtual u64 CallStackGetNextPC(u64 pc)
{
return pc + 4;
}
protected:
virtual void DoReset()=0;
virtual void DoRun()=0;

View file

@ -2059,7 +2059,7 @@ private:
void BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk)
{
if(!CheckCondition(bo, bi)) return;
CPU.SetBranch(branchTarget((aa ? 0 : CPU.PC), bd));
CPU.SetBranch(branchTarget((aa ? 0 : CPU.PC), bd), lk);
if(lk) CPU.LR = CPU.PC + 4;
}
void SC(s32 sc_code)
@ -2074,9 +2074,8 @@ private:
}
void B(s32 ll, u32 aa, u32 lk)
{
CPU.SetBranch(branchTarget(aa ? 0 : CPU.PC, ll));
CPU.SetBranch(branchTarget(aa ? 0 : CPU.PC, ll), lk);
if(lk) CPU.LR = CPU.PC + 4;
CPU.m_call_stack.Push(branchTarget(aa ? 0 : CPU.PC, ll)); //This does not affect emulation
}
void MCRF(u32 crfd, u32 crfs)
{
@ -2085,9 +2084,8 @@ private:
void BCLR(u32 bo, u32 bi, u32 bh, u32 lk)
{
if(!CheckCondition(bo, bi)) return;
CPU.SetBranch(branchTarget(0, CPU.LR));
CPU.SetBranch(branchTarget(0, CPU.LR), true);
if(lk) CPU.LR = CPU.PC + 4;
CPU.m_call_stack.Pop(); //This does not affect emulation
}
void CRNOR(u32 crbd, u32 crba, u32 crbb)
{
@ -2136,7 +2134,7 @@ private:
{
if(bo & 0x10 || CPU.IsCR(bi) == (bo & 0x8))
{
CPU.SetBranch(branchTarget(0, CPU.CTR));
CPU.SetBranch(branchTarget(0, CPU.CTR), true);
if(lk) CPU.LR = CPU.PC + 4;
}
}