public override void ToX86(X86Gen gen) { foreach (var node in nodes) { node.ToX86(gen); } }
public override void ToX86(X86Gen gen) { foreach (var declaration in declarations) { declaration.ToX86(gen); } }
public override void ToX86(X86Gen gen) { foreach (var stmt in stmts) { stmt.ToX86(gen); } }
public override void ToX86(X86Gen gen) { gen.Comment(X86Gen.Seg.TEXT, ToString()); if (expr == null) { gen.Inst(X86Gen.jmp, label); return; } var ret = expr.ToX86Expr(gen); switch (expr.Type.Kind) { case TKind.CHAR: case TKind.SCHAR: case TKind.UCHAR: if (ret == X86Gen.Ret.PTR) { gen.Inst(X86Gen.mov, X86Gen.al, X86Gen.eax.Addr(X86Gen.Size.BYTE)); } gen.Inst(X86Gen.jmp, label); return; case TKind.SHORT: case TKind.USHORT: if (ret == X86Gen.Ret.PTR) { gen.Inst(X86Gen.mov, X86Gen.ax, X86Gen.eax.Addr(X86Gen.Size.WORD)); } gen.Inst(X86Gen.jmp, label); return; case TKind.ENUM: case TKind.PTR: case TKind.UINT: case TKind.ULONG: case TKind.INT: case TKind.LONG: if (ret == X86Gen.Ret.PTR) { gen.Inst(X86Gen.mov, X86Gen.eax, X86Gen.eax.Addr()); } gen.Inst(X86Gen.jmp, label); return; case TKind.DOUBLE: if (ret == X86Gen.Ret.PTR) { gen.Inst(X86Gen.movsd, X86Gen.xmm0, X86Gen.eax.Addr(X86Gen.Size.QWORD)); } gen.Inst(X86Gen.sub, X86Gen.esp, 8); gen.Inst(X86Gen.movsd, X86Gen.esp.Addr(X86Gen.Size.QWORD), X86Gen.xmm0); gen.Inst(X86Gen.fld, X86Gen.esp.Addr(X86Gen.Size.QWORD)); gen.Inst(X86Gen.add, X86Gen.esp, 8); gen.Inst(X86Gen.jmp, label); return; } throw new NotImplementedException(); }
/// <summary> /// Generate the code for this compound statement, /// with label placed at the end of the block. /// { /// ... /// label: /// } /// </summary> /// <param name="gen"></param> /// <param name="label"></param> public void ToX86WithLabel(X86Gen gen, string label) { foreach (var stmt in stmts) { stmt.ToX86(gen); } gen.Tag(X86Gen.Seg.TEXT, label); }
/// <summary> /// structure: /// first_label: /// # body { /// ... /// continue_label: ; /// } /// # pred /// jmp first_label /// break_label: /// /// </summary> /// <param name="gen"></param> public override void ToX86(X86Gen gen) { gen.Comment(X86Gen.Seg.TEXT, "do body"); gen.Tag(X86Gen.Seg.TEXT, firstLabel); body.ToX86WithLabel(gen, continueLabel); gen.Comment(X86Gen.Seg.TEXT, "do pred"); gen.Branch(expr, firstLabel, true); gen.Comment(X86Gen.Seg.TEXT, "do end"); gen.Tag(X86Gen.Seg.TEXT, breakLabel); }
public override void ToX86(X86Gen gen) { if (initializer != null) { var ret = obj.ToX86Expr(gen); Debug.Assert(ret == X86Gen.Ret.PTR); gen.Inst(X86Gen.push, X86Gen.eax); initializer.Initialize(gen); gen.Inst(X86Gen.pop, X86Gen.eax); } }
public static string CGen(string src) { var results = Parse(src, Parser.TranslationUnit().End(), true); Assert.AreEqual(1, results.Count()); Assert.IsFalse(results.First().Remain.More()); var ast = results.First().Value.ToAST(new lcc.SyntaxTree.Env()); var gen = new lcc.AST.X86Gen(); ast.ToX86(gen); return(gen.ToString()); }
/// <summary> /// Basic structure: /// /// first_label: /// # pred /// je break_label /// # body /// jmp first_label /// break_label: /// /// </summary> /// <param name="gen"></param> public override void ToX86(X86Gen gen) { gen.Comment(X86Gen.Seg.TEXT, "while pred"); gen.Tag(X86Gen.Seg.TEXT, firstLabel); gen.Branch(expr, breakLabel, false); gen.Comment(X86Gen.Seg.TEXT, "while body"); body.ToX86WithLabel(gen, continueLabel); gen.Inst(X86Gen.jmp, firstLabel); gen.Comment(X86Gen.Seg.TEXT, "while end"); gen.Tag(X86Gen.Seg.TEXT, breakLabel); }
public override void ToX86(X86Gen gen) { env.Dump(gen); /// Append '_' to the function name. gen.Tag(X86Gen.Seg.TEXT, "_" + name, isGlobal); gen.Inst(X86Gen.push, X86Gen.ebp); gen.Inst(X86Gen.mov, X86Gen.ebp, X86Gen.esp); gen.Inst(X86Gen.sub, X86Gen.esp, env.size); body.ToX86(gen); gen.Tag(X86Gen.Seg.TEXT, returnLabel); gen.Inst(X86Gen.add, X86Gen.esp, env.size); gen.Inst(X86Gen.pop, X86Gen.ebp); gen.Inst(X86Gen.ret); }
public override void Initialize(X86Gen gen) { var ret = expr.ToX86Expr(gen); switch (type.Kind) { case TKind.CHAR: case TKind.SCHAR: case TKind.UCHAR: if (ret == X86Gen.Ret.PTR) { gen.Inst(X86Gen.mov, X86Gen.al, X86Gen.eax.Addr(X86Gen.Size.BYTE)); } gen.Inst(X86Gen.mov, X86Gen.ecx, X86Gen.esp.Addr()); gen.Inst(X86Gen.mov, X86Gen.ecx.Addr(X86Gen.Size.BYTE), X86Gen.al); break; case TKind.SHORT: case TKind.USHORT: if (ret == X86Gen.Ret.PTR) { gen.Inst(X86Gen.mov, X86Gen.ax, X86Gen.eax.Addr(X86Gen.Size.WORD)); } gen.Inst(X86Gen.mov, X86Gen.ecx, X86Gen.esp.Addr()); gen.Inst(X86Gen.mov, X86Gen.ecx.Addr(X86Gen.Size.WORD), X86Gen.ax); break; case TKind.INT: case TKind.UINT: case TKind.LONG: case TKind.ULONG: case TKind.PTR: case TKind.ENUM: if (ret == X86Gen.Ret.PTR) { gen.Inst(X86Gen.mov, X86Gen.eax, X86Gen.eax.Addr(X86Gen.Size.DWORD)); } gen.Inst(X86Gen.mov, X86Gen.ecx, X86Gen.esp.Addr()); gen.Inst(X86Gen.mov, X86Gen.ecx.Addr(X86Gen.Size.DWORD), X86Gen.eax); break; default: throw new NotImplementedException(); } }
public void Dump(X86Gen gen) { gen.Comment(X86Gen.Seg.TEXT, string.Format("Frame Size: {0}", size)); gen.Comment(X86Gen.Seg.TEXT, string.Format("{0, -10} {1, -5} {2, -10} {3, -20}", "EBP", "UID", "SYMBOL", "TYPE" )); foreach (var o in objs) { gen.Comment(X86Gen.Seg.TEXT, string.Format("{0, -10} {1, -5} {2, -10} {3, -20}", o.ebp, o.uid, o.symbol, o.type )); } }
public override void ToX86(X86Gen gen) { gen.Comment(X86Gen.Seg.TEXT, "if"); gen.Branch(expr, other != null ? elseLabel : endIfLabel, false); /// Generate code for then branch. /// Remember to jump to endif label since /// "If the first substatement is reached via a label, the second substatement is not executed. gen.Comment(X86Gen.Seg.TEXT, "then"); then.ToX86(gen); gen.Inst(X86Gen.jmp, endIfLabel); if (other != null) { gen.Comment(X86Gen.Seg.TEXT, "else"); gen.Tag(X86Gen.Seg.TEXT, elseLabel); other.ToX86(gen); } gen.Tag(X86Gen.Seg.TEXT, endIfLabel); }
public override void ToX86(X86Gen gen) { var ret = expr.ToX86Expr(gen); switch (expr.Type.Kind) { case TKind.INT: case TKind.LONG: /// Move the result to ecx. if (ret == X86Gen.Ret.PTR) { gen.Inst(X86Gen.mov, X86Gen.ecx, X86Gen.eax.Addr()); } else { gen.Inst(X86Gen.mov, X86Gen.ecx, X86Gen.eax); } /// For each case. foreach (var c in cases) { var cRet = c.Item2.ToX86Expr(gen); Debug.Assert(cRet == X86Gen.Ret.REG); gen.Inst(X86Gen.cmp, X86Gen.eax, X86Gen.ecx); gen.Inst(X86Gen.je, c.Item1); } /// Jump to default label. gen.Inst(X86Gen.jmp, defaultLabel); break; default: throw new NotImplementedException(); } /// Lay the code for the body. stmt.ToX86(gen); /// Lay down the break label. gen.Tag(X86Gen.Seg.TEXT, breakLabel); }
/// <summary> /// The basic structure is like: /// /// # init /// jmp first_label /// second_plus_label: /// # iter /// first_label: /// # pred /// je break_label /// # body /// jmp second_plus_label /// break_label: /// /// </summary> /// <param name="gen"></param> public override void ToX86(X86Gen gen) { /// Generate the initialize code. /// Jump to first_label if iter is not omitted. gen.Comment(X86Gen.Seg.TEXT, "for init"); if (init != null) { init.ToX86(gen); if (iter != null) { gen.Inst(X86Gen.jmp, firstLabel); } } /// Generate the iterate code. gen.Comment(X86Gen.Seg.TEXT, "for iter"); if (iter != null) { gen.Tag(X86Gen.Seg.TEXT, secondPlusLabel); iter.ToX86(gen); } /// Generate the controlling (predicating) code. gen.Comment(X86Gen.Seg.TEXT, "for pred"); gen.Tag(X86Gen.Seg.TEXT, firstLabel); gen.Branch(pred, breakLabel, false); /// Generate body code. gen.Comment(X86Gen.Seg.TEXT, "for body"); body.ToX86WithLabel(gen, continueLabel); gen.Inst(X86Gen.jmp, iter != null ? secondPlusLabel : firstLabel); /// Generate break labe. gen.Comment(X86Gen.Seg.TEXT, "for end"); gen.Tag(X86Gen.Seg.TEXT, breakLabel); }
public virtual void ToX86(X86Gen gen) { throw new NotImplementedException(); }
/// <summary> /// Assume the pointer to the obj is at the top of the stack. /// </summary> /// <param name="gen"></param> public abstract void Initialize(X86Gen gen);
/// <summary> /// Do nothing. /// </summary> /// <param name="gen"></param> public override void ToX86(X86Gen gen) { }
public override void ToX86(X86Gen gen) { gen.Comment(X86Gen.Seg.TEXT, ToString()); gen.Inst(X86Gen.jmp, label); }
public override void ToX86(X86Gen gen) { gen.Tag(X86Gen.Seg.TEXT, label); stmt.ToX86(gen); }