public SubCode Parse(IList <IInstruction> instructions, uint taskStart, uint taskEnd) { var sindex = getIndex(taskStart); var currentIndex = sindex; var subcode = new SubCode(); var endIndex = getIndex(taskEnd); ParseRec(instructions, currentIndex, endIndex, subcode); return(subcode); }
public void Clone() { var s = new SubCode(); foreach (var x in VisitedInstructions) { s.VisitedInstructions.Add(x); } foreach (var x in Branches) { s.Branches.Add(x); } foreach (var x in Returns) { s.Returns.Add(x); } }
private Tuple <Node <IList <IInstruction> >, IList <Node <IList <IInstruction> > > > Builder(SubCode code) { var returnNodes = new List <Node <IList <MIPSI.IInstruction> > >(); var partitions = new List <uint>(); foreach (var x in code.Branches) { partitions.Add(x.Address); partitions.Add(x.Pointer - 1); } foreach (var x in code.FunctionCalls) { partitions.Add(x.CallerAddress); //partitions.Add(x.FunctionAddress); } foreach (var x in code.Jumps) { partitions.Add(x.From); partitions.Add(x.To); } var insts = code.VisitedInstructions.OrderBy(x => x.Key).ToDictionary(x => x.Key, y => y.Value); var nodes = new Dictionary <uint, Node <IList <IInstruction> > >(); partitions = partitions.OrderBy(x => x).ToList(); var currentNode = CreateNode(); var Root = currentNode; var currentPartition = partitions.Count > 0 ? partitions[0] : uint.MaxValue; var partitionIndex = 1; foreach (var x in insts) { currentNode.Content.Add(x.Value); nodes.Add(x.Key, currentNode); if (x.Key == currentPartition) { var newnode = CreateNode(); currentNode.Left = newnode; currentNode = newnode; currentPartition = partitionIndex < partitions.Count ? partitions[partitionIndex] : uint.MaxValue; partitionIndex++; } } foreach (var x in code.Branches) { var from = nodes[x.Address]; var to = nodes[x.Pointer]; //var notTaken = nodes[x.Address + 1]; //from.Left = notTaken; from.Right = to; } foreach (var x in code.Jumps) { var from = nodes[x.From]; var to = nodes[x.To]; from.Left = to; } foreach (var x in code.FunctionCalls) { var from = nodes[x.CallerAddress]; var returnPoint = nodes[x.CallerAddress + 1]; var func = Builder(x.FunctionBody); from.Left = func.Item1; foreach (var r in func.Item2) { r.Left = returnPoint; } } foreach (var x in code.Returns) { returnNodes.Add(nodes[x]); } return(new Tuple <Node <IList <IInstruction> >, IList <Node <IList <IInstruction> > > >(Root, returnNodes)); }
public Node <IList <MIPSI.IInstruction> > Build(SubCode code) { var Root = Builder(code).Item1; return(Root); }
private void ParseRec(IList <IInstruction> instructions, uint currentIndex, uint endIndex, SubCode subCode) { do { if (subCode.VisitedInstructions.ContainsKey(currentIndex)) { return; } var inst = instructions[(int)currentIndex]; CheckInstruction(inst); subCode.AddVisitedInstruction(currentIndex, inst); if (inst is ITypeInstruction) { var i = inst as ITypeInstruction; switch (i.Opcode) { case Opcode.Branch: case Opcode.BranchOnEqual: case Opcode.BranchOnGreaterThanZero: case Opcode.BranchOnLessThanOrEqualToZero: case Opcode.BranchOnNotEqual: var branchaddr = (uint)(currentIndex + (short)i.Immediate + 1); subCode.Branches.Add(new Branch(currentIndex + 1, branchaddr, subCode.VisitedInstructions.ContainsKey(branchaddr))); ParseRec(instructions, branchaddr, endIndex, subCode); break; } } else if (inst is RTypeInstruction) { var r = inst as RTypeInstruction; if (r.Function == RTypeFunction.JumpRegister && r.Rs == 31) { var nextIndex = currentIndex + 1; var ist = instructions[(int)(nextIndex)]; CheckInstruction(ist); subCode.AddVisitedInstruction(nextIndex, ist); subCode.Returns.Add(nextIndex); return; } } else if (inst is JTypeInstruction) { var j = inst as JTypeInstruction; if (j.JumpType == JumpType.JumpAndLink) { var fcnsubcode = new SubCode(); ParseRec(instructions, j.Target, endIndex, fcnsubcode); subCode.FunctionCalls.Add(new FunctionCall() { CallerAddress = currentIndex + 1, FunctionBody = fcnsubcode, FunctionAddress = j.Target }); } else { var nextIndex = currentIndex + 1; var ist = instructions[(int)(nextIndex)]; CheckInstruction(ist); subCode.AddVisitedInstruction(nextIndex, ist); currentIndex = j.Target; subCode.Jumps.Add(new Jump() { From = nextIndex, To = j.Target }); continue; } } currentIndex++; } while (currentIndex != endIndex + 1); }