예제 #1
0
 public override void ToX86(X86Gen gen)
 {
     foreach (var node in nodes)
     {
         node.ToX86(gen);
     }
 }
예제 #2
0
 public override void ToX86(X86Gen gen)
 {
     foreach (var declaration in declarations)
     {
         declaration.ToX86(gen);
     }
 }
예제 #3
0
 public override void ToX86(X86Gen gen)
 {
     foreach (var stmt in stmts)
     {
         stmt.ToX86(gen);
     }
 }
예제 #4
0
        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();
        }
예제 #5
0
 /// <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);
 }
예제 #6
0
 /// <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);
 }
예제 #7
0
 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);
     }
 }
예제 #8
0
        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());
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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();
            }
        }
예제 #12
0
 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
                                                    ));
     }
 }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        /// <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);
        }
예제 #16
0
 public virtual void ToX86(X86Gen gen)
 {
     throw new NotImplementedException();
 }
예제 #17
0
 /// <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);
예제 #18
0
 /// <summary>
 /// Do nothing.
 /// </summary>
 /// <param name="gen"></param>
 public override void ToX86(X86Gen gen)
 {
 }
예제 #19
0
 public override void ToX86(X86Gen gen)
 {
     gen.Comment(X86Gen.Seg.TEXT, ToString());
     gen.Inst(X86Gen.jmp, label);
 }
예제 #20
0
 public override void ToX86(X86Gen gen)
 {
     gen.Tag(X86Gen.Seg.TEXT, label);
     stmt.ToX86(gen);
 }