feat(analysis): add basic block model and SMC event type
This commit is contained in:
1 parent
1f3ed9595e
commit
a6c2b4f7d4
2 files changed
+120
No files matched your search
@@ -0,0 +1,90 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Chip8.Analysis;
|
||||||
|
|
||||||
|
public sealed class BasicBlock
|
||||||
|
{
|
||||||
|
readonly List<InstructionInfo> instructionList = new();
|
||||||
|
readonly List<ControlFlowEdge> successorList = new();
|
||||||
|
readonly List<ushort> predecessorList = new();
|
||||||
|
|
||||||
|
public BasicBlock(ushort startAddress)
|
||||||
|
{
|
||||||
|
this.startAddress = startAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ushort startAddress { get; }
|
||||||
|
|
||||||
|
public IReadOnlyList<InstructionInfo> instructions => instructionList;
|
||||||
|
public IReadOnlyList<ControlFlowEdge> successors => successorList;
|
||||||
|
public IReadOnlyList<ushort> predecessors => predecessorList;
|
||||||
|
|
||||||
|
public InstructionInfo terminator => instructionList[instructionList.Count - 1];
|
||||||
|
|
||||||
|
public InstructionInfo first => instructionList[0];
|
||||||
|
|
||||||
|
public ushort endAddress => terminator.address;
|
||||||
|
|
||||||
|
public ushort nextAddress => terminator.nextAddress;
|
||||||
|
|
||||||
|
public int byteLength
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int total = 0;
|
||||||
|
foreach (var instruction in instructionList)
|
||||||
|
{
|
||||||
|
total += instruction.byteLength;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int instructionCount => instructionList.Count;
|
||||||
|
|
||||||
|
public bool isReturn => terminator.flow == FlowEffect.Return;
|
||||||
|
|
||||||
|
public bool isCall => terminator.flow == FlowEffect.Call;
|
||||||
|
|
||||||
|
public bool isBranch => terminator.flow == FlowEffect.Branch;
|
||||||
|
|
||||||
|
public bool isUnconditionalJump => terminator.flow == FlowEffect.Jump;
|
||||||
|
|
||||||
|
public bool hasIndirectExit => terminator.flow == FlowEffect.IndirectJump;
|
||||||
|
|
||||||
|
public bool isTerminal => successorList.Count == 0;
|
||||||
|
|
||||||
|
internal void add(InstructionInfo instruction) => instructionList.Add(instruction);
|
||||||
|
|
||||||
|
internal void addSuccessor(ControlFlowEdge edge) => successorList.Add(edge);
|
||||||
|
|
||||||
|
internal void addPredecessor(ushort predecessor)
|
||||||
|
{
|
||||||
|
if (!predecessorList.Contains(predecessor))
|
||||||
|
{
|
||||||
|
predecessorList.Add(predecessor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string render()
|
||||||
|
{
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
builder.Append("block 0x").Append(startAddress.ToString("X4", CultureInfo.InvariantCulture));
|
||||||
|
builder.Append(" (").Append(instructionCount).Append(" instr, ").Append(byteLength).Append(" bytes)\n");
|
||||||
|
foreach (var instruction in instructionList)
|
||||||
|
{
|
||||||
|
builder.Append(" ").Append(instruction).Append('\n');
|
||||||
|
}
|
||||||
|
foreach (var edge in successorList)
|
||||||
|
{
|
||||||
|
builder.Append(" => ").Append(edge).Append('\n');
|
||||||
|
}
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() =>
|
||||||
|
"block@0x" + startAddress.ToString("X4", CultureInfo.InvariantCulture)
|
||||||
|
+ " [" + instructionCount + " instr]";
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Chip8.Analysis;
|
||||||
|
|
||||||
|
public sealed class SmcEvent
|
||||||
|
{
|
||||||
|
public SmcEvent(int step, ushort writerAddress, ushort targetAddress, byte oldValue, byte newValue)
|
||||||
|
{
|
||||||
|
this.step = step;
|
||||||
|
this.writerAddress = writerAddress;
|
||||||
|
this.targetAddress = targetAddress;
|
||||||
|
this.oldValue = oldValue;
|
||||||
|
this.newValue = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int step { get; }
|
||||||
|
public ushort writerAddress { get; }
|
||||||
|
public ushort targetAddress { get; }
|
||||||
|
public byte oldValue { get; }
|
||||||
|
public byte newValue { get; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "step " + step.ToString(CultureInfo.InvariantCulture)
|
||||||
|
+ ": writer 0x" + writerAddress.ToString("X4", CultureInfo.InvariantCulture)
|
||||||
|
+ " changed 0x" + targetAddress.ToString("X4", CultureInfo.InvariantCulture)
|
||||||
|
+ " from 0x" + oldValue.ToString("X2", CultureInfo.InvariantCulture)
|
||||||
|
+ " to 0x" + newValue.ToString("X2", CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user