public static Instruction Call(RegisterNode reg) { return(new Instruction( map => string.Format("call {0}", map [reg]), join(Target.CallerSavedRegisters, reg), Target.CallerSavedRegisters)); }
private ICollection <Instruction> DFS(Instruction instruction, RegisterNode register, Dictionary <RegisterNode, Vertex> registerToVertex, ICollection <Instruction> visited) { visited.Add(instruction); if (instruction.RegistersDefined.Contains(register)) { return(visited); } foreach (var reg in instruction.RegistersDefined) { if (instruction.IsCopyInstruction) { registerToVertex [reg].CopyNeighbors.Add(registerToVertex [register]); registerToVertex [register].CopyNeighbors.Add(registerToVertex [reg]); } else { registerToVertex [reg].NonCopyNeighbors.Add(registerToVertex [register]); registerToVertex [register].NonCopyNeighbors.Add(registerToVertex [reg]); } } foreach (var ins in instruction.PrevInstructions) { if (!visited.Contains(ins)) { visited = DFS(ins, register, registerToVertex, visited); } } return(visited); }
public SequenceNode FunctionCall(Function from, Node[] args, RegisterNode result, out Action <Node> nextNodeSetter) { var pl = _enclosedIn == null ? 0 : 1; // space for enclosing function stack frame address var seq = new Node[args.Length + Math.Max(0, args.Length - Target.HardwareRegistersOrder.Length) + 3 + pl]; // params in registers, params on stack, call, result, cleanup stack if (pl == 1) { seq[0] = new AssignmentNode(Target.HardwareRegistersOrder[0], from.ComputationOfStackFrameAddress(this)); } var i = 0; for (; i < Target.HardwareRegistersOrder.Length && i < args.Length; ++i) { seq[i + pl] = new AssignmentNode(Target.HardwareRegistersOrder[i], args[i]); } var ptr = i + pl; for (; i < args.Length; ++i) { var v = Push(args[i]); seq[ptr++] = v.Item1; seq[ptr++] = v.Item2; } seq[ptr++] = new FunctionCallNode(this); seq[ptr++] = new AssignmentNode(result, Body.Last().ResultRegister); // Assume value of function body is return value seq[ptr++] = new AssignmentNode(Target.RSP, new AddOperatorNode(Target.RSP, new ConstantNode <long>(_stackFrameSize))); return(new SequenceNode(seq, out nextNodeSetter, result)); }
public static Instruction Move(RegisterNode dst, RegisterNode src) { return(Instruction.CopyInstruction( map => (map [dst].ToString() == map [src].ToString()) ? "" : string.Format("mov {0}, {1}", map [dst], map [src]), use(src, dst), define(dst))); }
// dst = src * const public static Instruction Lea_Mul(RegisterNode dst, RegisterNode src, ConstantNode <long> c) { if (c.Value != 2L && c.Value != 4L && c.Value != 8L) { throw new ArgumentException("LEA instruction accepts only 2 4 8 as constant!"); } return(new Instruction( map => string.Format("lea {0}, [{1}*{2}]", map [dst], map [src], c.Value), use(dst, src), define(dst))); }
private void AnalyzeRegister(RegisterNode register, Dictionary <RegisterNode, Vertex> registerToVertex, IEnumerable <Instruction> instructions) { ISet <Instruction> whereUsed = new HashSet <Instruction> (); foreach (var instruction in instructions) { if (instruction.RegistersUsed.Contains(register)) { whereUsed.Add(instruction); } } ICollection <Instruction> visited = new HashSet <Instruction> (); foreach (var instruction in whereUsed) { visited = DFS(instruction, register, registerToVertex, visited); } }
static IEnumerable <Instruction> EffectiveMultiplication(RegisterNode dst, RegisterNode mul_reg, ConstantNode <long> mul_val) { switch (mul_val.Value) { case 2L: case 4L: case 8L: return(new [] { InstructionFactory.Lea_Mul(dst, mul_reg, mul_val) }); case 3L: case 5L: case 9L: var tmp_val = new ConstantNode <long> (mul_val.Value - 1L); return(new [] { InstructionFactory.Lea_MulAdd(dst, mul_reg, tmp_val, mul_reg) }); case 1L: return(new [] { InstructionFactory.Move(dst, mul_reg) }); case 0L: return(new [] { InstructionFactory.Xor(dst, dst) }); default: // dst = mul_reg * mul_val return(new [] { InstructionFactory.Move(Target.RAX, mul_val), // RAX = mul_val InstructionFactory.Mul(mul_reg), // RDX:RAX = mul_reg * mul_val InstructionFactory.Move(dst, Target.RAX) // dst = RAX }); } }
public static Instruction MoveToMemory(RegisterNode dst, RegisterNode src) { return(new Instruction( map => string.Format("mov [{0}], {1}", map [dst], map [src]), use(src, dst), define())); }
public static Instruction MoveFromMemory <T>(RegisterNode dst, ConstantNode <T> c) { return(new Instruction( map => string.Format("mov {0}, [{1}]", map [dst], c.Value), use(dst), define(dst))); }
public static Instruction MoveFromMemory(RegisterNode dst, RegisterNode src) { return(new Instruction( map => string.Format("mov {0}, [{1}]", map [dst], map [src]), use(src, dst), define(dst))); }
public static Instruction Cmp <T>(ConstantNode <T> c, RegisterNode right) { return(new Instruction( map => string.Format("cmp {0}, {1}", c.Value, map [right]), use(right), define())); }
static Instruction binopInstruction <T>(string mnemonik, RegisterNode dst, ConstantNode <T> c) { return(new Instruction( map => string.Format("{0} {1}, {2}", mnemonik, map [dst], c.Value), use(dst), define(dst))); }
// dst = src + const public static Instruction Lea_Add <T>(RegisterNode dst, RegisterNode src, ConstantNode <T> c) { return(new Instruction( map => string.Format("lea {0}, [{1}+{2}]", map [dst], map [src], c.Value), use(dst, src), define(dst))); }
public virtual Value evaluate(Context cx, RegisterNode node) { output("<RegisterNode position=\"" + node.pos() + "\"/>"); return(null); }
public static Instruction Setne(RegisterNode reg) { return(Set("ne", reg)); }
// dst = src1 + src2 public static Instruction Lea_Add(RegisterNode dst, RegisterNode src1, RegisterNode src2) { return(new Instruction( map => string.Format("lea {0}, [{1}+{2}]", map [dst], map [src1], map [src2]), use(dst, src1, src2), define(dst))); }
public static Instruction Set(string cond_type, RegisterNode reg) { return(new Instruction( map => string.Format("set{0} {1}", cond_type, map [reg]), use(reg), define(reg))); }
public static Instruction Cmovne(RegisterNode reg1, RegisterNode reg2) { return(Cmov("ne", reg1, reg2)); }
public static Instruction Cmov(string cond_type, RegisterNode reg1, RegisterNode reg2) { return(new Instruction( map => string.Format("cmov{0} {1}, {2}", cond_type, map[reg1], map[reg2]), use(reg1, reg2), define(reg1))); }
public static Instruction MoveToMemory <T>(RegisterNode dst, ConstantNode <T> val) { return(new Instruction( map => string.Format("mov [{0}], {1}", map [dst], val.Value), use(dst), define())); }
public Temporary() { _node = new TemporaryNode(); }
public static Instruction MoveToMemory <T>(ConstantNode <T> c, RegisterNode src) { return(new Instruction( map => string.Format("mov [{0}], {1}", c.Value, map [src]), use(src), define())); }
public virtual Value evaluate(Context cx, RegisterNode node) { output("<RegisterNode position=\"" + node.pos() + "\"/>"); return null; }
/// <summary> /// Use this constructor to wrap existing instance of TemporaryNode /// </summary> /// <param name="nodeToWrap"></param> public Temporary(RegisterNode nodeToWrap) { _node = nodeToWrap; }
public static Instruction Jmp(RegisterNode reg) { return(new Instruction( map => string.Format("jmp {0}", map [reg]), use(reg), define())); }
public override void Visit(RegisterNode node) { Visit(node as LocationNode); }
// dst = src1 * const1 + src2 + const2 public static Instruction Lea_MulAdd <T>(RegisterNode dst, RegisterNode src1, ConstantNode <long> c1, RegisterNode src2, ConstantNode <T> c2) { return(new Instruction( map => string.Format("lea {0}, [{1}*{2}+{3}+{4}]", map [dst], map [src1], c1.Value, map [src2], c2.Value), use(dst, src1, src2), define(dst))); }
public Vertex(RegisterNode register) { this.Register = register; CopyNeighbors = new HashSet <Vertex> (); NonCopyNeighbors = new HashSet <Vertex> (); }
public static Instruction Shr <T>(RegisterNode reg, ConstantNode <T> c) { return(binopInstruction("shr", reg, c)); }
public virtual void Visit (RegisterNode node) { Visit (node as LocationNode); }
public static Instruction Cmp <T>(RegisterNode left, ConstantNode <T> c) { return(new Instruction( map => string.Format("cmp {0}, {1}", map [left], c.Value), use(left), define())); }