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